Azure AD AcquireToken无法使用应用程序密码。

4
我正在使用.NET ADAL库验证Azure AD中用户的密码。对于没有MFA的常规用户帐户,这很好用,但是在为启用了MFA的用户执行此操作时遇到了问题。
当我使用用户的实际密码时,我得到了“AADSTS50076:需要应用程序密码”的错误,这是合理的,但是当我创建一个新的应用程序密码时,我收到了“AADSTS70002:验证凭据时出错。AADSTS50020:用户名或密码无效”的错误。我已经创建了多个应用程序密码,但它们都无法工作。
尝试进行身份验证的代码如下:
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需要用户交互。 - Rick Rainey
难道这不是应用程序密码的作用吗?为了能够登录那些无法使用MFA登录的东西?例如,我已经创建了这些密码以便在我的智能手机/Outlook上登录Office 365。此外,错误消息明确表示我应该创建一个应用程序密码来进行身份验证。 - MLowijs
是的,正如您在问题中指出的那样,它适用于未配置MFA的用户。 - Rick Rainey
当然,没有启用多因素身份验证的用户不需要创建应用程序密码,因为他们可以使用常规密码登录。我的意思是,错误消息让人觉得可以使用应用程序密码登录。在其他地方使用应用程序密码登录是有效的。这两个事实结合起来让我认为它也应该在这里起作用。 - MLowijs
如果这是一个新用户,您可能会被提示创建新密码,就像您第一次尝试以该用户身份登录时一样。 - Rick Rainey
两个用户都是现有用户,已经在初始登录后完成了密码更改过程。 - MLowijs
1个回答

2

所以,为了回答自己的问题,我采取了以下措施(经过简化):

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吗)? - GaTechThomas
我不知道;我没有与Startup类一起使用过它。IAuthenticationProvider是我的,为了清晰起见已将其删除。 - MLowijs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接