B2C Authority String doesn't work with MSAL4J - msal

We're implementing Microsoft B2C and I am charged with using MSAL4J 1.13.4 for our java-based web-app clients. I've been provided with an Authority string but it doesn't work against MSAL4J due to the format:
https://sadoenswb2c.b2clogin.com/sadoenswb2c.onmicrosoft.com/b2c_1a_dta_single_abn_authentication/
The MSAL4J source code accepts three types of format, AAD, ADFS, and B2C. None of those Authority types work with the above. The B2CAuthority type error is:
275345 [nio-8080-exec-4] INFO sw.mw.msal.BusinessHubAuthUtil - Authority: https://sadoenswb2c.b2clogin.com/sadoenswb2c.onmicrosoft.com/b2c_1a_dta_single_abn_authentication
275413 [nio-8080-exec-4] ERROR .nsw.mw.msal.BusinessHubFilter - Exception that is not a MsalException
java.lang.IllegalArgumentException: Unsupported authority type. Please use B2C authority
at com.microsoft.aad.msal4j.AbstractClientApplicationBase$Builder.b2cAuthority(AbstractClientApplicationBase.java:243)
This is expected due to the code, the URL is lacking the "tfp" segment. But my server-side team claims their URLs are standard and should be usable.
On examination of the source I can see the Builder pattern in use (which is great) but both the PublicClientApplication and ConfidentialClientApplication classes are fully encapsulated. It doesn't seem to be possible to pass in an Authority subclass that I could customize to our own situation.
Any help on this would be appreciated. I guess confirmation that the server team is actually giving us a valid B2C Authority would help, or if anyone has used MSAL4J and had it work with B2C.

I solved this with the help of a friend. Even though it is counter-intuitive, if you input a URL constructed from the segments of host, tenant, and policy, and add in the tfp segment, the MSAL4J library will accept it and do the right thing. So the Authority string is more of a spec than an actual URL. This not explained anywhere in the Microsoft Azure doco.

Related

SspiPromptForCredentials Target Name

I've been developing an application that uses SSPI for Client / Server authentication. Everything works fine, but still one question remains.
The first argument of SspiPromptForCredentials is the target name... But what is it really used for?
I can literally put anything as a target name, my code will work. I don't even see it written anywhere (in the GUI).
Is it related to the authentication method? I use Negotiate.
Thanks for your help :)
I think it might be related to how the credentials are saved in the credential manager.
The only SspiPromptForCredentials example I can find on MSDN just uses a simple useless string ("Target").
For CredUIConfirmCredentials MSDN says:
Pointer to a null-terminated string that contains the name of the target for the credentials, typically a domain or server application name.
This must be the same value passed as pszTargetName to CredUIPromptForCredentials or CredUICmdLinePromptForCredentials
CredUICmdLinePromptForCredentials has a similar parameter and for this MSDN says:
A pointer to a null-terminated string that contains the name of the target for the credentials, typically a server name.
The pszTargetName parameter is used to identify the target information and is used to store and retrieve the credential.
...
Credentials are stored in the credential manager based on target name. Each target name is stored as generally as possible without colliding with credentials already stored in the credential manager. An important effect of storing credentials by target name is that a particular user can have only one credential per target stored in the credential manager.
These other CredUI functions are perhaps lower-level but I think the parameter usage is the same.
MSDN says this about Negotiate:
To allow Negotiate to select the Kerberos security provider, the client application must provide a service principal name (SPN), a user principal name (UPN), or a NetBIOS account name as the target name. Otherwise, Negotiate always selects the NTLM security provider.
The answer is a little more benign than you might think. SSPI supports arbitrary credential types, so the API needs to provide a way to prompt for credentials that a particular SSP understands without having to expose a 3rd party API. You can't launch a UI from within the SSP itself because it runs in LSA, so there's an implicit contract between the app builder and the SSP builder that if you need special credentials you're going to have to call SspiPromptForCredentials.
In some cases it's possible that SSP you're trying to use might require knowledge of the target to form the shape of the marshaled credential. Often times it doesn't.
Negotiate just happens to not require that information because the credentials you enter are not dependent on the target.

WindowsDeviceGroup claims

ADFS 2016 supports a new claim type "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup" which contains the Windows devices group SIDs. How may I cast the claims on a simple claims aware ASP.Net Application ? I am on VS 2015, .Net 4.6. What are the minimum requirements to grab this claim type and its value from ADFS so I may use it. Any code snippet would be highly appreciated.
I need help in getting the code that can do something like this but for a Windows Device -
ClaimType - http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup , ClaimValue - S-1-21-5-xxxx-xyyyy-zzzzzz.
Where S-1-21-5-xxxx-xyyyy-zzzzzz is the SID of a Group the computer is member of.
Also, Any chance that this claim type may be used with ADFS 2012R2 ?
This uses the compound authentication pattern that was released as part of WS2012 Active Directory. See https://www.microsoft.com/en-us/download/confirmation.aspx?id=36830 for details on it. Look for the compound authentication section. Then you need to pass the necessary claims by modifying the ADFS's claims provider trust for "Active Directory". Now you have those claims that can be consumed by a downstream application.
Note that this works through Kerberos. So, only if the client is inside the corporate network with line of sight to the a correctly enabled domain controller, will this use case light up.
Thanks
//Sam (#MrADFS)

Linking Auth0 and Parse Server users

I am writing an app that uses Parse Server, with Auth0 as the authentication provider. For unrelated reasons, we need to use Auth0 rather than Parse for user management.
I'm having trouble figuring out how to "link" a user authenticated via Auth0 to Objects in Parse Server. Without this, the authenticated user will not have permission to write to his/her Objects on the Parse Server. I believe my issue is similar to this question, which has no solution: here.
I have found many articles discussing the migration of users from Parse to Auth0, but am finding surprisingly little documentation on how to link those users to Parse. There is one article (I believe written by the same person who posted the question I linked to), but I couldn't get it to work, and it involves storing passwords in cleartext in Javascript.
I thought to create a default Parse user that would simply own all the objects in Parse. This would be invisible to the authenticated end-user so they wouldn't know, but that's just security by obscurity and doesn't seem like a good approach.
If anyone has suggestions on how to approach this, or has done it before, I'm interested to read your suggestions. Thank you very much.
Auth0 supports the most common and used authentication protocols (OAuth2/OIDC, SAML and WS-Federation) so configuring an application to rely on Auth0 is really easy when that application already talks one of the previously mentioned protocols.
According to the Parse Server Wiki, it does support custom authentication leveraging OAuth so that seems your best starting point for integrating Auth0 with a Parse Server based application.
It is possible to leverage the OAuth support with any 3rd party authentication that you bring in.
Disclaimer: I never used the Parse service or Parse Server so I'm assuming that when you mean linking Parse objects to users this can be accomplished by simply having an authenticated user in Parse and the identity of that user is just verified and proven by Auth0 instead of something like built-in username/passwords managed by Parse itself.

Secure WebAPI using HMAC. How to store passwords?

I'm new to WebAPI and before I dive too deep, I would like to first secure the Web API application first. After days of research, I just found one approach that's straight forward.
Looking over this post How to secure an ASP.NET Web API, I understand overall how it works and it's great there is a github source for it too. (Most answers I found just describe the generic concept with no code to back it up)
My question is, how do you store this "Shared Secret Key" on the server which typically is user's password? I'm doing a ASP.NET MVC 4 app with provided membership provider and it stores the user passwords with salt.
Obviously, the salt value is randomly generated per user and it's not likely the end user knows what their salt value is.
So then, what do you do?
PS: Am I missing some well known frameworks that handle this? I know Microsoft encourages mobile app developments and want developers to create new apps, but how am I suppose to do this when I can't even build authentication for Web API easily? Sorry, just a bit frustrated.
HMAC is not typically used for authenticating users to an API. It's typically used to authenticate "trusted" systems to an API. Example: Company A wants to access Company B's protected API, but doesn't need to authenticate at the user level.
When doing HMAC, you need to have the shared secret available in clear text on both the client and server so that both systems can create the exact same request signature hash. Although you may want to store the shared secret in an encrypted format, it must be a two-way (reversible) encryption.

Google Apps Premium Edition: which authentication mechanism to use?

Our company has a web application that is only used internally by our employees. We also have Google Apps Premier Edition. We would like to make it so our employees can log into our private web application using the Google Apps account that they already have.
Requirements: We want to display our own login form. We don't want to pass the email/password in plain text through the internet.
Which authentication mechanism should we use to achieve this?
Note: our application is written in PHP using Zend Framework (if that matters).
I would look into some combination of OpenID and your domain users (i.e. only let those at domain.com can log in).
Google API
They also have libraries for PHP and other languages that you can leverage to make this happen.
EDIT:
Some more info
When it comes to integrate Google Apps and an internally used private system, we simply have two options.
Use Google as the authentication center. Modify the private system to authenticate at Google's server. We could use OpenID or AuthSub. Check http://code.google.com/apis/accounts/docs/OpenID.html and http://code.google.com/apis/accounts/docs/AuthSub.html for more information.
Use the private system as the authentication center. In this case, we have to implement SAML protocol in the private server and configure Google Apps's SSO settings. Check http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html for more information.
It is easier to accomplish SSO with the first method since there's already bunch of OpenID libraries out there. But, as you described in the requirements, you want to use your own login form. So I guess you have to go with the second method.
BTW, if your private system has to get or set information from Google, you may want to use OAuth for authorization. See http://code.google.com/apis/accounts/docs/OAuth.html for more information.
Use the ClientLogin API, it does exactly what you're after: allow you to verify username and password. (the link goes to provisioning API doco but that is not relevant here)
Pro's:
you get to use you own login form
Cons:
you don't get SSO with Google Apps, i.e. users already in Apps will be prompted to login again (you didn't mention that as a requirement, but it seems a reasonable thing to want)
Google won't like you (they're trying to discourage ProgrammaticLogin.
you will get occasional CAPTCHA tests you'll need to show your users.
OpenID specifically prevents you from displaying your own login page, so if that's a hard requirements, Programmatic Login is really your only choice.
Going the SSO route let's you do pretty much anything, but may be a bit of overkill to take on authentication for the whole domain to make one app authenticate in a nicer fashion? If you really want to go down this route, check out SimpleSAMLphp.

Resources