【问题标题】:Azure AD AcquireToken does not work with app passwordAzure AD AcquireToken 不适用于应用密码
【发布时间】:2015-03-31 10:55:05
【问题描述】:

我正在尝试使用 .NET ADAL 库验证 Azure AD 中的用户密码。 这适用于没有 MFA 的普通用户帐户,但我遇到了为已激活 MFA 的用户执行此操作的问题。

当我使用用户的实际密码时,我得到了AADSTS50076: Application password is required.,这很公平,但是当我创建一个新的应用程序密码时,我收到了错误AADSTS70002: Error validating credentials. AADSTS50020: Invalid username or password。我已经创建了多个应用密码,但它们都不起作用。

用于尝试验证的代码如下:

var ac = new AuthenticationContext("https://login.windows.net/my-tenant.com");
var authResult = ac.AcquireToken("https://graph.windows.net", "my-client-id", new UserCredential("my.account@my-tenant.com", "my-password"));

尝试进行身份验证的用户是此 AD 中的全局管理员。

是否可以对具有 MFA 的用户进行这样的身份验证?

【问题讨论】:

  • 这是不可能的,因为 MFA 需要用户交互。
  • 这不就是应用程序密码的用途,能够登录到使用 MFA 无法登录的东西吗?例如,我已经创建了用于在我的智能手机/Outlook 上登录 Office 365 的那些。此外,错误消息明确指出我应该创建一个应用密码来进行身份验证。
  • 是的,正如您在问题中指出的那样,它适用于未配置 MFA 的用户。
  • 当然;没有 MFA 的用户不能也不需要创建应用密码,因为他们可以使用常规密码登录。我想说的是,错误消息使它看起来可以使用应用程序密码登录。使用应用程序密码登录在其他地方可以正常工作。这两个事实结合起来让我认为它也应该在这里工作。
  • 如果这是一个新用户,系统可能会提示您创建新密码,就像您第一次尝试以该用户身份登录一样。

标签: c# azure azure-active-directory


【解决方案1】:

因此,为了稍微回答我自己的问题,我采取了以下措施(为简洁起见):

public class AzureAdAuthenticationProvider
{
    private const string AppPasswordRequiredErrorCode = "50076";
    private const string AuthorityFormatString = "https://login.windows.net/{0}";
    private const string GraphResource = "https://graph.windows.net";

    private AuthenticationContext _authContext;
    private string _clientId;

    public AzureAdAuthenticationProvider()
    {
        var tenantId = "..."; // Get from configuration

        _authContext = new AuthenticationContext(string.Format(AuthorityFormatString, tenantId));
    }

    public bool Authenticate(string user, string pass)
    {
        try
        {
            _authContext.AcquireToken(GraphResource, _clientId, new UserCredential(user, pass));

            return true;
        }
        catch (AdalServiceException ase)
        {
            return ase.ServiceErrorCodes.All(sec => sec == AppPasswordRequiredErrorCode);
        }
        catch (Exception)
        {
            return false; // Probably needs proper handling
        }
    }
}

它不漂亮,但它可以完成工作。

通过使用ServiceErrorCodes.All(),我确保只有在出现单个 AppPasswordRequired 错误时,身份验证成功。

此方法的唯一缺点是启用 MFA 的用户必须使用其实际帐户密码才能登录。似乎不支持使用应用密码。

【讨论】:

  • 我希望能够重现这一点。这个类如何与罐装的 Startup 类挂钩?另外,IAuthenticationProvider 是在哪里定义的(它只是你的 IoC)?
  • 我不知道;我没有将它与 Startup 类一起使用。 IAuthenticationProvider 是我的,为了清楚起见将其删除。
猜你喜欢
  • 2018-12-21
  • 2018-03-09
  • 1970-01-01
  • 2019-10-07
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
相关资源
最近更新 更多