由于B2C登录策略允许用户选择“让我登录”,当我的 B2C Web应用程序启动时,我需要知道用户是否仍然经过身份验证,因此我知道是否显示“登录”或“注销”菜单项。
User.Identity.IsAuthenticated 在您第一次调用时总是响应错误,但在第一次调用'[Authenticate]'方法后似乎有效。
以下是我的启动代码:
/// <summary>
/// Configure the services that are available through Dependency Injection.
/// </summary>
/// <param name="services">A collection of services.</param>
public void ConfigureServices(IServiceCollection services)
{
// Configure DI to use authentication options, the Business to Consumer policies, and the API service options.
services.Configure<ClientAuthenticationOptions>(this.configuration.GetSection("ClientAuthentication"));
services.Configure<B2CPolicyOptions>(this.configuration.GetSection("B2CPolicies"));
services.Configure<ServiceOptions>(this.configuration.GetSection("Service"));
// These proxies are used to access the Web API. This will eventually be replaced with a repository.
services.AddTransient<ServiceProxy>();
// Make MVC services availble for Dependency Injection.
services.AddMvc(options => options.Filters.Add(typeof(ReauthenticationRequiredFilter)));
// Add Kendo UI service to the service container.
services.AddKendo();
// Configure additional classes to be instantiated through DI.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// A distributed memory cache is used to manage the cookies.
services.AddDistributedMemoryCache();
// At this point we can build the service provider.
var serviceProvider = services.BuildServiceProvider();
// The SSO requires a distributed cache to preserve the user's security token.
this.distributedCache = serviceProvider.GetService<IDistributedCache>();
services.AddSingleton(this.distributedCache);
// This is where the Authentication system is configured. We're using cookies to preserve the user's security tokens between calls to
// the Web API, and we're using OpenID Connect protocol for authentication with the B2C service.
this.clientAuthenticationOptions = serviceProvider.GetService<IOptions<ClientAuthenticationOptions>>().Value;
this.b2CpolicyOptions = serviceProvider.GetService<IOptions<B2CPolicyOptions>>().Value;
services.AddAuthentication(options => Startup.GetAuthenticationOptions(options))
.AddCookie()
.AddOpenIdConnect(Constants.OpenIdConnectAuthenticationScheme, options => this.GetOpenIdConnectOptions(options));
}
这就是我退出时的所作所为:
/// <summary>
/// Remove the user's authorization.
/// </summary>
/// <returns>The result of this action.</returns>
public async Task<IActionResult> SignOut()
{
if (this.User.Identity.IsAuthenticated)
{
await this.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var callbackUrl = this.Url.Action("SignOutCallback", "Account", values: null, protocol: this.Request.Scheme);
var policyDictionary = new Dictionary<string, string> { { Constants.B2CPolicy, this.User.FindFirst(Constants.TfpClaimType).Value } };
await this.HttpContext.SignOutAsync(
Constants.OpenIdConnectAuthenticationScheme,
new AuthenticationProperties(policyDictionary) { RedirectUri = callbackUrl });
// This process may take a few seconds, so this page provides feedback that we're trying to log them out.
return this.View();
}
// If the user isn't authenticated the just redirect them to the home page.
return this.RedirectToPage("/" + nameof(Index));
}
/// <summary>
/// Completes the sign-out action asynchronously.
/// </summary>
/// <returns>The result of this action.</returns>
public IActionResult SignOutCallback()
{
if (this.HttpContext.User.Identity.IsAuthenticated)
{
// Redirect to home page if the user is authenticated.
return this.RedirectToPage("/" + nameof(Index));
}
return this.View();
}