我有一个配置了 B2C 身份验证的 Blazor 服务器端应用程序。 该应用程序将调用 webapi 与我的服务进行任何数据交换。 B2C 身份验证工作正常,并且直接从模板配置 B2C 身份验证是:
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => { Configuration.Bind("AzureAdB2C", options); });
这些声明仅包含我从登录策略返回的声明,没有任何可用于代表我的 Web api 进行身份验证的访问令牌(也由相同的 B2C 租户保护)。
我已经阅读了大约 100 个不同的文档,但在 blazor 的上下文中似乎没有任何意义。 之前有没有人做过这件事可以透露一些信息?
一等奖是在用户第一次对 B2C 进行身份验证后请求访问令牌,然后将令牌保留在缓存中,以便在会话/浏览器打开或访问令牌有效时在 blazor 应用程序中用于任何 api 调用.
似乎这是正确的路径:https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi/blob/master/TaskWebApp/Controllers/TasksController.cs但是我不明白的是:
谢谢!
我在这里为您创建了一个使用 OpenId Connect 和 Blazor(服务器)的示例应用程序 https://github.com/yberstad/BlazorAuth。它使用 SameSiteCookie 和 OpenId Connect。
如何获取访问和刷新令牌:
var accessToken = await HttpContext.GetTokenAsync("access_token");
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
SameSiteCookie 信息: https://brockallen.com/2019/01/11/same-site-cookies-asp-net-core-and-external-authentication-providers/
将令牌存储在 SameSiteCookie 中使其仅对服务器可见,因此不会在客户端的不安全环境中保存和公开它。 SameSiteCookie 对于 XSS 也是安全的。
希望这有帮助。
我自己解决了这个问题。 我的 AcquireTokenSilent 调用失败,因为调用它时缓存中没有用户,因此我必须确保在用户登录时将第一个条目添加到缓存中。我可以通过如下配置身份验证来实现此目的:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = AzureADB2CDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = AzureADB2CDefaults.OpenIdScheme;
})
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options))
.AddCookie();
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
//Configuration.Bind("AzureAdB2C", options);
options.ResponseType = Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectResponseType.CodeIdToken;
options.Scope.Add("offline_access");
options.Scope.Add("https://mytenant.onmicrosoft.com/api/api.read.write");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Events.OnAuthorizationCodeReceived = async context =>
{
AzureADB2COptions opt = new AzureADB2COptions();
Configuration.Bind("AzureAdB2C", opt);
// As AcquireTokenByAuthorizationCodeAsync is asynchronous we want to tell ASP.NET core that we are handing the code
// even if it's not done yet, so that it does not concurrently call the Token endpoint. (otherwise there will be a
// race condition ending-up in an error from Azure AD telling "code already redeemed")
context.HandleCodeRedemption();
var code = context.ProtocolMessage.Code;
string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(opt.ClientId)
.WithB2CAuthority(opt.Authority)
.WithRedirectUri(opt.RedirectUri)
.WithClientSecret(opt.ClientSecret)
.WithClientName("myWebapp")
.WithClientVersion("0.0.0.1")
.Build();
new MSALStaticCache(signedInUserID, context.HttpContext).EnablePersistence(cca.UserTokenCache);
try
{
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCode(opt.ApiScopes.Split(' '), code)
.ExecuteAsync();
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
catch (Exception)
{
}
};
});
这是一个简单的步骤。在登录过程中,确保您拥有 Tokenmemoryacquisition 和缓存,以便令牌将存储在应用程序的缓存中,您可以检索它。
在 program.cs:
.EnableTokenAcquisitionToCallDownstreamApi) .AddInMemoryTokenCaches();
创建一个服务来获取该令牌
例如:
您可以在这里看到令牌并使用它!!