我有一个针对 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;
}