1

我正在使用 ADALiOS 访问 OneDrive for business 服务,并在帐户消歧后使用以下代码段对用户进行身份验证,

    ADAuthenticationContext *context = ....

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

Web 身份验证 UI 将提示,并允许用户输入凭据以继续。这里的问题是,在此页面中,用户还可以将用户 id 更改为“userB@mydomain.com”,完成块将被调用,并出现类似“不同用户已通过身份验证。预期 userA@mydomain.com,实际 userB”的错误@mydomain.com”。我使用 ADALiOS 错了吗?

4

2 回答 2

3

当您指定 userId 时,ADAL 假定它已被指定,因为那确实是您想要的用户。如果生成的用户不是所要求的用户,那么您会收到您所看到的错误。如果您不关心哪个用户已通过身份验证,则可以将 nil 作为 userId 参数传递,您将不会收到错误消息。

ADAL 库出于过分谨慎而这样做。尽管 userId 参数意味着什么,但当您调用 ADAL 时,ADAL 无法保证您将获得您请求的用户的令牌。它会尽力而为。如果它可以在缓存中找到该用户的令牌,那么它将返回它。但是,如您所见,如果调用了交互式流程,则没有什么可以阻止用户输入与请求的用户名不同的用户名。在这种情况下,将返回不同用户的令牌。如果应用程序将某些 UI 元素或私有资源与特定的 userId 相关联,会发生什么情况?如果它获得的令牌与请求的用户不同,那么它可能会以对应用程序用户不明显的方式混合用户。如果用户最初以低权限用户身份登录,但随后以管理员身份登录,并且应用程序没有注意到这一点,那么可能会发生不好的事情。因此,库假定如果您要求特定用户,那么这是唯一可以接受的用户。

接下来的内容可能比您需要的更详细,但为了完整起见,我将继续。不幸的是,userId 参数被重载用于三种不同的目的。

  1. 作为缓存查找键。如果 ADAL 之前已对传递的用户进行身份验证,并且在缓存中有该用户的令牌或刷新令牌,则它可以直接查找该令牌并避免对 AAD 请求的任何需求。如果您一次只对单个用户进行身份验证,那么这不会添加任何值,因为 ADAL 将尝试查找对已传递资源有效的令牌。

  2. 作为对服务器的登录提示。userId 用于预填充用户名字段,以方便用户使用。但是,用户可以随意删除该用户名并提供不同的用户名。

  3. 作为家庭领域发现的提示。如果用户是联合用户,这意味着 AAD 需要引用 ADFS(或其他一些联合服务器)进行身份验证,它需要一个用户名来确定它应该引用的服务器的地址。通常这是通过两步过程完成的。用户首先登陆 AAD 页面并输入他们的用户名。一旦用户名字段失去焦点,服务器就会查找用户名,如果它是联合用户,它就会开始将他们重定向到他们的 ADFS 服务器。最后,用户登陆 ADFS 登录页面,他们发现他们的用户名已经填写。他们输入密码并完成身份验证。但是,如果您传递 userId 参数,则其值将传递给 AAD。因此,

如果您需要 2 或 3,但您不关心 1,则有一种解决方法。您可以为 userId 指定 nil,但添加“login_hint="username" 作为 extraQueryParameters 参数。将“username”替换为您将在 userId 参数中传递的用户名。如果您这样做,那么 ADAL 将忘记您的用户已请求,但 AAD 会将用户名解释为预填充用户名字段的登录提示,并作为主域发现提示。确保用户请求的用户是返回的用户的检查将被绕过。您需要非常请注意,您可能无法获得作为 login_hint 提供的用户的令牌。您应该确保在对用户是谁或他们可能有权访问什么做出任何假设之前验证该用户。

于 2014-11-04T02:59:13.347 回答
1

@Ryan Pangrle 是对的。

如果安装了 Microsoft Authenticator,上述解决方法可能不再正常工作。

自 ADAL 2.1+ 以来,ADAL 一直提供以下 API 来解决此问题:

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

开发人员可以在 (ADUserIdentifier*)userId 参数中将 UPN 匹配设置为可选。

于 2017-03-27T20:23:56.820 回答