来自 .NET 应用程序的 Azure Sql 服务器 MFA 连接

Azure Sql Server MFA connection from .NET application

我的目标是允许用户使用他们的 Azure Active Directory 凭据连接到我们的 Azure Sql 服务器。我正在尝试按照本文中的步骤进行操作,但遇到无法解决的错误:
Connect to Azure SQL Database with Azure Multi-Factor Authentication

下面是我的代码的相应部分,我主要从文章中的示例中复制了这些代码(除了我的应用程序是用 VB.NET 编写的,所以我不得不翻译)。它需要我从 NuGet 获得的 Microsoft.IdentityModel.Clients.ActiveDirectory 程序集。

Public Module DB
    Private ConnectionProvider As ActiveDirectoryAuthProvider

    'Gets run at application start    
    Public Sub SetProvider()
        ConnectionProvider = New ActiveDirectoryAuthProvider
        SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, ConnectionProvider)
    End Sub
End Module

'I can't believe Microsoft doesn't just have this as a class that's already been written
Public Class ActiveDirectoryAuthProvider
    Inherits SqlAuthenticationProvider

    Private ReadOnly _clientId As String = "Our Client ID From The Azure Portal"
    Private ReadOnly _redirectUri As New Uri("A Valid URL")

    Public Overrides Async Function AcquireTokenAsync(parameters As SqlAuthenticationParameters) As Task(Of SqlAuthenticationToken)
        Dim authContext As New AuthenticationContext(parameters.Authority)
        authContext.CorrelationId = parameters.ConnectionId
        Dim result As AuthenticationResult

        Select Case parameters.AuthenticationMethod
            Case SqlAuthenticationMethod.ActiveDirectoryInteractive
                result = Await authContext.AcquireTokenAsync(parameters.Resource, _clientId, _redirectUri, New PlatformParameters(PromptBehavior.Auto), New UserIdentifier(parameters.UserId, UserIdentifierType.RequiredDisplayableId))
            Case SqlAuthenticationMethod.ActiveDirectoryIntegrated
                result = Await authContext.AcquireTokenAsync(parameters.Resource, _clientId, New UserCredential())
            Case SqlAuthenticationMethod.ActiveDirectoryPassword
                result = Await authContext.AcquireTokenAsync(parameters.Resource, _clientId, New UserPasswordCredential(parameters.UserId, parameters.Password))
            Case Else
                Throw New InvalidOperationException()
        End Select

        Return New SqlAuthenticationToken(result.AccessToken, result.ExpiresOn)
    End Function

    Public Overrides Function IsSupported(ByVal authenticationMethod As SqlAuthenticationMethod) As Boolean
        Return authenticationMethod = SqlAuthenticationMethod.ActiveDirectoryIntegrated OrElse authenticationMethod = SqlAuthenticationMethod.ActiveDirectoryInteractive OrElse authenticationMethod = SqlAuthenticationMethod.ActiveDirectoryPassword
    End Function
End Class

'And finally, I create new connections like this:
New SqlConnection($"Server=tcp:ourserver.database.windows.net,1433;Initial Catalog=OurDatabase;TrustServerCertificate=True;Pooling=False;Encrypt=True;Authentication=""Active Directory Interactive"";User ID={Environment.UserName}@OurDomain.com;")

使用此代码,当我 运行 SqlConnection.Open 时,我确实收到了 Azure 的弹出窗口,要求我登录。但是,一旦我登录,我就会收到以下异常:

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException
AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.

知道我该如何解决这个问题吗?

因此,在挖掘我能找到的所有资源时,我遇到了这个问题: “error_description”:"AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'

上面链接的答案指出 "Redirect URI" 在 Azure 中注册的应用程序是问题的原因。

我的问题中的 Microsoft 文章指出:"For this article, any valid value is fine for RedirectUri, because it isn't used here." 他们使用的示例是:“https://mywebserver.com/”。

与 Microsoft 的引用相反,我上面链接的答案指出 Azure 使用重定向 URI 来确定正在注册的应用程序的类型。将我公司网站的 URI 更改为“https://login.microsoftonline.com/common/oauth2/nativeclient”解决了我的问题。 URL 是 Azure 允许您选择的默认值之一。它显然向 Azure 表明您正在注册本机应用程序,而不是 Web 应用程序。一旦 Azure 知道这一点,它似乎就不再要求“'client_assertion' 或 'client_secret'”,我只能假设这是 Web 应用程序身份验证所需的东西。

我早些时候遇到过这个问题,花了很多时间来解决问题,唯一有帮助的解决方案是在 "Authentication" 选项卡上添加“https://login.microsoftonline.com/common/oauth2/nativeclient”到 "Redirect URIs" 就像 Keith Stein 提到的那样