首页 文章

Active Directory B2C onBehalfOf对SQL Azure的身份验证

提问于
浏览
0

我有一个应用程序,用于针对Azure Active Directory对用户进行身份验证 . 然后,返回的JWT令牌从应用程序传递到验证令牌的Web API .

然后,我要求Active Directory代表SQL Azure用户生成另一个JWT令牌 . Web API现在可以使用OnBehalfOf令牌向SQL Azure进行身份验证 . 从这里开始,数据库通过使用JWT中的一些唯一信息来实现RLS(行级安全性),以相应地过滤结果 .

为此,用于请求onBehalfOf令牌的Active Directory应用程序必须具有SQL Azure的requiredResourceAccess . 这是通过编辑Azure门户中的应用程序清单来完成的,该清单指定SQL Azure(022907d3-0f1b-48f7-badc-1ba6abab6d66)可以访问Azure SQL DB和数据仓库(c39ef2d1-04ce-46dc-8b5f-e9a5c60f0fc9) .

"requiredResourceAccess": [
    {
      "resourceAppId": "022907d3-0f1b-48f7-badc-1ba6abab6d66",
      "resourceAccess": [
        {
          "id": "c39ef2d1-04ce-46dc-8b5f-e9a5c60f0fc9",
          "type": "Scope"
        }
      ]
    }
  ]

我想支持社交登录,Azure B2C通常更适合我的要求 . 但Azure Active Directory B2C是否可以支持此身份验证流程?

const string tenant = "...";
const string clientId = "...";
const string clientSecret = "...";
const string connectionString = "Server=...database.windows.net,1433;Initial Catalog=...;Persist Security Info=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False";

async Task Main()
{
    try
    {
        var authenticationContext = new AuthenticationContext(TenantSettings.Authority);

        var result = await authenticationContext.AcquireTokenAsync(
            "https://database.windows.net/",
            new ClientCredential(clientId, clientSecret),
            new UserAssertion("eyJ...")).ConfigureAwait(false);

        await ConnectToDatabaseAsync(result.AccessToken.Dump());
    }
    catch (Exception ex)
    {
        $"Failed to connect to Azure SQL.\n\tReason: {ex.Message}".Dump();
    }
}

private static async Task ConnectToDatabaseAsync(string accessToken)
{
    using (var connection = new SqlConnection(connectionString))
    {
        connection.AccessToken = accessToken;
        await connection.OpenAsync().ConfigureAwait(false);

        using (var command = new SqlCommand("select USER_NAME()", connection))
        using (var reader = await command.ExecuteReaderAsync())
        {
            await reader.ReadAsync().ConfigureAwait(false);
            reader.GetString(0).Dump("User");
        }
    }
}

private static class TenantSettings
{
    public const string Authority = Instance + Tenant;
    public const string Instance = "https://login.microsoftonline.com/";
    public const string Tenant = tenant;
}

1 回答

相关问题