基于令牌的数据库身份验证失败,“用户登录失败'NT AUTHORITY \ ANONYMOUS LOGON'。”

问题描述 投票:3回答:1

我无法获得基于令牌的数据库身份验证。使用Active Directory密码连接有效,但在与令牌连接时,我收到以下错误:

用户'NT AUTHORITY \ ANONYMOUS LOGON'登录失败。

这个问题已经讨论过here on Stack Overflowhere on MSDN,但没有解决方案可用。 This blog post表示用户权限有问题,但它相当含糊。

Configuration

使用以下方法获取令牌成功:

static async Task<string> GetAccessToken()
{
    var certificateSDN = "redacted";
    var tenantId = "redacted";
    var clientId = "redacted";
    var resource = "https://database.windows.net";

    X509Certificate2 certificate;
    using (var certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
    {
        certificateStore.Open(OpenFlags.ReadOnly);
        certificate = certificateStore.Certificates
            .Find(X509FindType.FindBySubjectDistinguishedName, certificateSDN, false)
            [0];
    }

    var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");
    var clientAssertionCertificate = new ClientAssertionCertificate(clientId, certificate);
    var authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientAssertionCertificate);

    return authenticationResult.AccessToken;
}

连接到数据库的方式如下:

var connectionStringBuilder = new SqlConnectionStringBuilder()
{
    DataSource = "redacted.database.windows.net",
    InitialCatalog = "redacted",
};
using (var sqlConnection = new SqlConnection(connectionStringBuilder.ConnectionString))
{
    sqlConnection.AccessToken = accessToken;
    sqlConnection.Open();
}

调用sqlConnection.Open()时会发生错误。

clientId匹配应用程序注册的应用程序ID。我在数据库中创建了一个用户,该应用程序注册的名称与以下查询匹配:

create user [redacted] from external provider
go
exec sp_addrolemember N'db_datareader', N'redacted'
exec sp_addrolemember N'db_datawriter', N'redacted'

Diagnostics

通过以下查询,我检查用户是否具有角色并具有连接数据库的权限:

declare @user nvarchar(max);
set @user = 'redacted'

select
    u.name
    ,r.name
from
    sys.database_role_members as m
    inner join sys.database_principals as r on m.role_principal_id = r.principal_id
    inner join sys.database_principals as u on u.principal_id = m.member_principal_id
where
    u.name = @user;

select
    class_desc
    ,major_id
    ,permission_name
    ,state_desc
from
    sys.database_permissions
where
    grantee_principal_id = user_id(@user);

这是输出:

redacted    db_datareader
redacted    db_datawriter

DATABASE    0   CONNECT GRANT

尝试连接伪造令牌会产生同样的错误。所以我不知道我的令牌是否有问题,或者数据库配置是否有问题。我可以执行哪些其他诊断,以找出此问题的原因?

azure authentication azure-sql-database azure-active-directory adal
1个回答
8
投票

事实证明这是一个非常小的错误:resource最后需要一个最后的斜线。

而不是

var resource = "https://database.windows.net";

它需要

var resource = "https://database.windows.net/";
© www.soinside.com 2019 - 2024. All rights reserved.