ADAL iOS - A different user has been authenticated. Expected user A@mydomain.com , actual userB@mydomain.com

I am using ADALiOS to access OneDrive for the business service, and I am using the snippet below to authenticate the user after the values ​​have been resolved,

ADAuthenticationContext *context = .... [context acquireTokenWithResource:resource clientId:clientId redirectUri:redirectUri promptBehavior:AD_PROMPT_ALWAYS userId:@" userA@mydomain.com " extraQueryParameters:@"" completionBlock:^(ADAuthenticationResult *result) { ... } 

The web authentication user interface will prompt and allow the user to enter credentials to continue. The problem here is that on this page the user can also change the user ID to " userB@mydomain.com ", and the completion block will be called with an error, for example, "Different user has been authenticated. Expected user A@mydomain.com , actual user @mydomain. com ". Am I using ADALiOS incorrectly?

0
source share
2 answers

When you specify userId, ADAL assumes that it was specified, because it is really the user you wanted. If the resulting user is not the one that was requested, then you will receive the error message that you see. If you don't care which user is authenticated, you can pass nil as the userId parameter and you will not get an error.

The ADAL library does this because of excess caution. Although the userId parameter implies when you call ADAL, ADAL cannot guarantee that you will get a token for the user you requested. He will do his best. If he can find the token for this user in the cache, he will return it. However, as you saw, if the interactive thread is invoked, nothing prevents the user from entering a different username than the one that was requested. In this case, the token for another user will be returned. What happens if an application is associated with certain user interface elements or with private resources with a specific user? If he receives a token for another user than was requested, then he can mix users in a way that is not obvious to the application user. If a user initially signed up as a user with low privileges, but subsequently signed him up as an administrator, and the application did not notice this, then bad things can happen. Thus, the library assumes that if you ask for a specific user, then this is the only user that is acceptable.

What follows is probably more detailed than you need, but just to be complete, I will continue. The userId parameter, unfortunately, is overloaded for three different purposes.

  • As a cache search key. If ADAL has previously authenticated a past user and has a token or update token for that user in the cache, he can directly look for that token and avoid the need for an AAD request. If you only ever authenticate one user at a time, this does not add any value, as ADAL will try to find the token valid for the transferred resource.

  • As a hint to enter the server. UserId is used to prefill the username field as a convenience to the user. However, the user can erase this username and provide another.

  • As a hint for opening a home area. If the user is a federated user, which means that AAD needs to refer to ADFS (or some other federation server) for authentication, a username is required to determine the address of the server to which it must refer. This is usually done through a two-step process. The user first lands on the AAD page and enters his username. As soon as the username field loses focus, the server looks at the username and, if it is a federated user, it redirects them to its ADFS server. Finally, the user lands on the ADFS login page, and they find their username already populated. They enter their password and authentication ends. However, if you pass the userId parameter, its value is passed to AAD. As a result, AAD no longer needs to wait until the user types in their username and can send them directly to the federation server, excluding one page and allowing the user to directly go to the login.

If you need 2 or 3, but you don't care 1, this is a workaround. You can specify nil for userId, but add "login_hint =" username "as the extraQueryParameters parameter. Replace the" username "with the username you passed in the userId parameter. If you do this, ADAL will ignore the user who you asked, but AAD will interpret the username as a login hint to pre-populate the username field, as well as a search hint in the home world. Verifying that the user has requested will be returned to the user will be bypassed. that you are not my ete get a token for the user that you have provided both login_hint. You should make sure that you check the user before making any assumptions about who they are or what they may have access.

+2
source

@Ryan Pangrle is right.

The above work may not work properly if Microsoft Authenticator is installed.

ADAL provides the following API to solve this problem with ADAL 2.1+:

 - (void)acquireTokenWithResource:(NSString*)resource clientId:(NSString*)clientId redirectUri:(NSURL*)redirectUri promptBehavior:(ADPromptBehavior)promptBehavior userIdentifier:(ADUserIdentifier*)userId extraQueryParameters:(NSString*)queryParams completionBlock:(ADAuthenticationCallback)completionBlock; 

where developers can set the UPN match as optional in the userId (ADUserIdentifier *) parameter.

0
source

All Articles