使用 Active Directory B2C 保护 Blazor WASM 应用程序和 Web API
Using Active Directory B2C to secure a Blazor WASM app and Web API
我有一个场景,我有一个通过 AD B2C 保护的 Blazor WASM(仅限客户端)应用程序。根据我已阅读的文档,我已在 AD B2C 中注册了一个应用程序(例如 BlazorApp)并将 Blazor 应用程序连接到此实例。此 Blazor 应用程序 API 调用 .NET Core Web API,其中端点是安全的(使用 [Authorize] 属性)。根据我阅读的文档,我还在 AD B2C(例如 WebApi)中注册了 Web API 并连接了 API 以连接到此实例。
我遇到的问题是,当我在 Blazor 应用程序中进行身份验证,然后通过 API 调用传递 access/id 令牌时,Web API 无法对其进行身份验证令牌(未经授权的错误响应)。当我连接 Web API 以连接到 BlazorApp 注册时,它会起作用(我猜是因为这是颁发令牌的地方)。但这似乎违背了在 AD 中将每个 app/api 注册为单独注册的建议。
如何获得 WebApi 注册以识别 BlazorApp 颁发的令牌?我是不是做错了,我应该只连接 Web API 来与 BlazorApp 实例对话吗?
附加信息:
Blazor WASM(客户端)- Program.cs
(已删除敏感信息)
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/blazorapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/blazorapp/app.write");
});
...
await builder.Build().RunAsync();
}
Blazor WASM(客户端)- appsettings.json
(已删除敏感信息)
{
"AzureAdB2C": {
"Authority": "https://<tenant name>.b2clogin.com/<tenant name>.onmicrosoft.com/B2C_1_SignUpSignIn",
"ClientId": "<BlazorApp Application ID>",
"ValidateAuthority": false
}
}
网络 API (.NET Core 3.1) - StartUp.cs
(已删除敏感信息)
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
services.AddControllers();
...
}
网络 API (.NET Core 3.1) - appsettings.json
(已删除敏感信息)
注意:当我用 BlazorApp 应用程序 ID 替换 WebApi 应用程序 ID 时身份验证有效
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<WebAPI Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}
您的项目没有使用OBO流,OBO流需要三个应用程序,具体一个client-side
和两个api-side
,参见here。
回到问题,首先你的问题是范围配置错误,因为 api-side
应用程序需要公开它自己的 api
,你的 blazor 应用程序端的 API
权限获取对 api-side
的访问权限,因此对范围的访问权限是在 api-side
上配置的,因此我们需要将 https://<tenant name>.onmicrosoft.com/webapiapp/app.read
放在范围上,您的 blazor 应用程序仅用于配置访问权限。
之所以有效,是因为你使用blazor app请求blazor app自己的api
,这是可行的,虽然有点奇怪,自己请求。
所以对于你的项目,正确的请求应该是这样的。
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/webapiapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/webapiapp/app.write");
});
...
await builder.Build().RunAsync();
}
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}
我有一个场景,我有一个通过 AD B2C 保护的 Blazor WASM(仅限客户端)应用程序。根据我已阅读的文档,我已在 AD B2C 中注册了一个应用程序(例如 BlazorApp)并将 Blazor 应用程序连接到此实例。此 Blazor 应用程序 API 调用 .NET Core Web API,其中端点是安全的(使用 [Authorize] 属性)。根据我阅读的文档,我还在 AD B2C(例如 WebApi)中注册了 Web API 并连接了 API 以连接到此实例。
我遇到的问题是,当我在 Blazor 应用程序中进行身份验证,然后通过 API 调用传递 access/id 令牌时,Web API 无法对其进行身份验证令牌(未经授权的错误响应)。当我连接 Web API 以连接到 BlazorApp 注册时,它会起作用(我猜是因为这是颁发令牌的地方)。但这似乎违背了在 AD 中将每个 app/api 注册为单独注册的建议。
如何获得 WebApi 注册以识别 BlazorApp 颁发的令牌?我是不是做错了,我应该只连接 Web API 来与 BlazorApp 实例对话吗?
附加信息:
Blazor WASM(客户端)- Program.cs (已删除敏感信息)
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/blazorapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/blazorapp/app.write");
});
...
await builder.Build().RunAsync();
}
Blazor WASM(客户端)- appsettings.json (已删除敏感信息)
{
"AzureAdB2C": {
"Authority": "https://<tenant name>.b2clogin.com/<tenant name>.onmicrosoft.com/B2C_1_SignUpSignIn",
"ClientId": "<BlazorApp Application ID>",
"ValidateAuthority": false
}
}
网络 API (.NET Core 3.1) - StartUp.cs (已删除敏感信息)
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
services.AddControllers();
...
}
网络 API (.NET Core 3.1) - appsettings.json (已删除敏感信息)
注意:当我用 BlazorApp 应用程序 ID 替换 WebApi 应用程序 ID 时身份验证有效
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<WebAPI Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}
您的项目没有使用OBO流,OBO流需要三个应用程序,具体一个client-side
和两个api-side
,参见here。
回到问题,首先你的问题是范围配置错误,因为 api-side
应用程序需要公开它自己的 api
,你的 blazor 应用程序端的 API
权限获取对 api-side
的访问权限,因此对范围的访问权限是在 api-side
上配置的,因此我们需要将 https://<tenant name>.onmicrosoft.com/webapiapp/app.read
放在范围上,您的 blazor 应用程序仅用于配置访问权限。
之所以有效,是因为你使用blazor app请求blazor app自己的api
,这是可行的,虽然有点奇怪,自己请求。
所以对于你的项目,正确的请求应该是这样的。
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/webapiapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(@"https://<tenant name>.onmicrosoft.com/webapiapp/app.write");
});
...
await builder.Build().RunAsync();
}
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}