how to sign in to two Azure Active Directories - azure

We have a web application where users have to authenticate against our active directory. This works fine. But when a user already has session with another Azure Active Directory say a corporate office 365 or something, the user gets an error trying to authenticate to us.
Is there some sort of setting (a domain ID, or some sort of token ID which makes it possible to differentiate these two sessions and make it possible to use our waad as a stand alone authentication service?

Can you provide the actual error and the services you are authenticating against?
In general you can easily differentiate between different logged in users by using the login_hint in ADAL and passing the UPN of the user who you wish to access from the cache. ADAL will do the heavily lifting of looking in to the cache and prompting the user for credentials if the tokens for that user has expired.

Related

user login with ROPC flow with AAD

When using ROPC flow with AAD does the invited user share the same credentials (username, password) which he must be using on other AAD tenant\MS account.
I see that ROPC is not a recommended flow as our client should not handle the credentials. But just wanted to know what we are compromising other then training user for Phishing sites and loosing some important features like MFA etc.
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
e. g if I have my account in Parent Azure directory (A) and I am invited guest\member in Azure directory (B). Then for the Enterprise SPA App (whichever directory it belongs to) user using ROPC flow will use the same username, password for login into the app. This would compromise both the Azure account if the credentials are hacked. So is there a way when we invite user they should not be associated with existing Azure directory (i.e A or B).
So is there a way when we invite user they should not be associated
with existing Azure directory (i.e A or B)?
In short, NO.
When you choose ROPC flow, it means you need to take the risks. Whether you use ROPC flow in your own tenant or in another tenant, your credentials are at risk of leakage.
Therefore, if you are worried about this, choosing an alternative authentication flow is your first choice.
I assume that you simply do not want to log in interactively, then you can consider client credential flow, which can easily access the data in both Tenant A and B.
One major concern is already that you have mentioned. The Client is handling the credentials. There will be high trust that needs to be put on the client.
In addition to the above mentioned, the below points might be in consideration for you that I could think of :
On using the ROPC grant type, there is no way to distinguish if the resource owner (the user) is really making that request or the client is making the request.
Federated identity is also unavailable to this grant type
Not applicable for the Live Accounts (#outlook.com,#hotmail.com etc)
SSO is also not feasible.
If you are hashing and storing the password locally, if there is a password expiry - then this will fail.

B2B with Microsoft Graph

As you probably know, I am creating a multi-tenant azure application, which is using the B2B functionallity.
I am testing the B2B functionality and after some research I got a working sample.
Small summary: User authenticates against common authority, first token is acquired via common authority with the authorization code and from then, everytime I need a service client, I try to obtain those tokens from the 'current tenants' authority.
When I request 'Me', it only works against the home tenant. When I request me with a trusted tenant, I got an error that my user identifier does not exist in the directory. Probably because user does not actually exist in the trusted tenant.
When I request Users, it works fine. I can get both, home tenant users and trusted tenant users.
Is this normal behaviour?
Is this something I need to handle programmatically or would this been solved by using the AD graph?
(So when I know I need user info, just query the home tenant?)
Or is this a bug?
Any thoughts on this would be greatly appreciated!
Guests added to a directory via the B2B Collaboration feature will not work correctly on multi-tenant apps or the Microsoft Graph if you're using the common endpoint.
The common endpoint will always authenticate the user against his/her home tenant, not against any tenant where (s)he is a guest.
In order to successfully query /me for a guest, you'll need to have them sign-in through the tenant specific endpoint for the tenant where they're a guest.
See my answer to this other post for a more in-depth explanation / context:
Can users from an unmanaged Azure AD directory, sign into an Azure AD multi-tenant application which resides in a different directory?
I have noticed that when you want to switch between tenants, you need to re-authorize against the current tenant.
I got it working this way:
1. First sign-in needs to be done against the common endpoint.
2. Every time I need a token for certain resource, I try to get the token silently.
=> This can throw 2 different AdalSilentTokenAcquisitionException
Nothing found in cache, also no refresh token found
=> In this case, I redirect the user to the login page again.
When you switch between tenants, and it is the first time you want to login using a tenant where you've been trusted, you can get a error like: User or admin should be given consent for this application. Although the admin from his home tenant has added the application in the directory for the home tenant. Anyone who knows why this consent is needed? So tenant A and tenant B admins have both been given consent. Why does a trusted user from B in A still needs to consent someway?
I was able to trigger the consent flow by redirecting the user to the authorization request URL.
So when I got an AdalSilentTokenAcquisitionException, and the error code is "failed_to_acquire_token_silently" then I had to redirect the user to the URL generated by the authContext (authenticationContext.GetAuthorizationRequestUrlAsync) when the cache had been cleared, no refresh token will be found, then redirect the user to resign.

Azure AD with prompt=none shows Bad Request when user is logged in into another tenant

We have an application that supports seamless login with our Azure AD tenant account via OpenID Connect implicit flow. If user is authorized to access the app providing Azure AD issued evidence - access will be granted automatically, otherwise we show regular application login screen.
Every time when user authentication is required we redirect the user to the Azure AD login page (https://login.microsoftonline.com/xyz) specifying prompt=none.
Respecting the ODIC specification such flag should have the following effect.
The Authorization Server MUST NOT display any authentication or
consent user interface pages. An error is returned if an End-User is
not already authenticated or the Client does not have pre-configured
consent for the requested Claims or does not fulfill other conditions
for processing the request. The error code will typically be
login_required, interaction_required. This can be used as a method to
check for existing authentication and/or consent.
It generally works as expected, however, there is a case where Azure AD login page will show an error screen to the End User and it happens when User logged into another Azure AD tenant.
User account '...' from identity provider
'https://sts.windows.net/.../' does
not exist in tenant '...' and cannot access the
application '...' in that tenant. The
account needs to be added as an external user in the tenant first.
Sign out and sign in again with a different Azure Active Directory
user account.
The questions are:
Does not it violate the ODIC specification?
How to properly handle such cases in seamless for users fashion? (app is not in charge of what is going on after redirect to Azure AD).
Though I also agree that this is a violation of the spec, can I offer a workaround?
I believe you can try specifying domain_hint or login_hint parameter as well to help the system determine valid session. Hope it would give you the right answer regardless of which session user is signed in at the moment.
Yes, this is a violation of the OIDC spec. We have created a bug.
If the error is only occurring because the STS is selecting the wrong session, you could use login_hint or domain_hint to help the STS select the right session.
Yes, that is in violation of the spec and defeats the purpose of prompt=none since the the application can't keep control of the user experience anymore. #vibronet may be able to set the record straight on MS side.

Checking a user exists in Azure Active Directory B2C

I am creating a new Azure AD B2C authenticated site to replace an older Forms Authenticated one. In the new site, I am asking the user to initially enter their email address so I can check if they exist in Azure B2C and send them to the appropriate sign-in page and if not send them to the older Forms Authenticated site.
The issue is I have when following Microsoft's tutorials, is that they show user management but they all require you to have logged in with your Azure account first and obviously this is not possible given the system I am trying to build. Is what I am doing even possible?
Thanks in advance!
MS tutorials: https://azure.microsoft.com/en-gb/documentation/articles/active-directory-code-samples/
Sadly, it seems like this is not possible within the Azure B2C Preview.
From the limitations section (https://azure.microsoft.com/en-gb/documentation/articles/active-directory-b2c-limitations/) there is this paragraph which describes what I am trying to do:
Daemons / Server Side Applications
Applications that contain long running processes or that operate without the presence of a user also need a way to access secured resources, such as Web APIs. These applications can authenticate and get tokens using the application's identity (rather than a consumer's delegated identity) using the OAuth 2.0 client credentials flow. This flow is not yet available in Azure AD B2C preview - which is to say that applications can only get tokens after an interactive consumer sign-in flow has occurred.
So it seems like this is currently not possible. Hopefully it'll work once it comes out of preview.
Be careful with this, check if your site is not vulnerable to username enumeration:
http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html
With the old users going to forms based authentication, you could call the Graph API to create the users in the B2C directory:
https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/
Then the next time they can login through B2C

Create an Azure app (webforms .net asp) and use SigleSignOn on and Windows Server Active Directory (not a WAAD)

I have a website (azure), that has a login page for the user to insert it's username and password.
Currently, the login is using LDAP to autenticate the user.
Now the client wants to use/activate the single sign on functionality, but using their Windows Server Active Directory (they don't want to use the Azure Active Directory).
Is this possible to do? Whats the best approach?
These are the two options I know:
You can use Microsoft Active Directory Federation Services (aka ADFS). This is a component that should be installed in your customer infrastructure and talks with the AD, your website will talk WS-Federation with ADFS. Authenticating a user means basically redirecting the user to a ADFS, if the user is in the LAN and is already authenticated to AD, ADFS will login automatically, but if is outside it will prompt user credentials.
Another approach will be to use a third party authentication broker. Auth0 is an authentication broker that you can add from the azure store, you will need to create an AD "Connection", which will require to install an small MSI on your customer infrastructure. For this case it works more or less like ADFS but your application talks OAuth with Auth0 rather than Ws-Federation so in lot of cases it is easier to implement.
Disclaimer: I work for Auth0.

Resources