Я создал BlazorApp1, приложение Blazor Webassembly с опцией ASP. NET Ядро размещено. В результате были созданы три проекта: BlazorApp1.Client, BlazorApp1.Server и BlazorApp1.Shared. Я создал настраиваемую политику авторизации, как описано в статье Криса Сейнти об авторизации на основе политик , добавив Policies.cs в BlazorApp1. Shared:
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
using System.Threading.Tasks;
namespace BlazorApp1.Shared
{
public class CompanyDomainRequirement : IAuthorizationRequirement
{
public string CompanyDomain { get; }
public CompanyDomainRequirement(string companyDomain)
{
CompanyDomain = companyDomain;
}
}
public class CompanyDomainHandler : AuthorizationHandler<CompanyDomainRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CompanyDomainRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.Email))
{
return Task.CompletedTask;
}
var emailAddress = context.User.FindFirst(c => c.Type == ClaimTypes.Email).Value;
if (emailAddress.EndsWith(requirement.CompanyDomain))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
}
Я добавил эту настраиваемую политику в BlazorApp1. Server.Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddAuthorization(config =>
{
config.AddPolicy("IsCompanyUser", policy =>
policy.Requirements.Add(new CompanyDomainRequirement("newco.com")));
});
services.AddSingleton<IAuthorizationHandler, CompanyDomainHandler>();
services.AddControllersWithViews();
services.AddRazorPages();
}
В BlazorApp1.Server.WeatherForecastController я добавил эту политику в атрибут Authorize:
using BlazorApp1.Shared;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
namespace BlazorApp1.Server.Controllers
{
[Authorize(Policy = "IsCompanyUser")]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
this.logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
Однако, когда я установил точку останова в CompanyDomainHandler .HandleRequirementAsyn c запустите приложение, войдите в систему, нажмите «Получить данные» и посмотрите context.User.Identity.Name в точке останова, я вижу, что он равен null и context.User.Identity.Claims не имеет имя или адрес электронной почты аутентифицированного пользователя.
![Debugger showing context.User in CompanyDomainHandler.HandleRequirementAsync](https://i.stack.imgur.com/cllqw.jpg)
However, in the client, LoginDisplay.razor correctly displays context.User.Identity.Name:
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
Привет, @ context.User.Identity.Name! Выйти Зарегистрироваться Войти @code {private asyn c Task BeginSignOut (MouseEventArgs args) {await SignOutManager.SetSignOutState (); Navigation.NavigateTo («аутентификация / выход»); }}
LoginDisplay.razor отображение context.User.Identity.Name
Как я могу определить context.User.Identity.Name в CompanyDomainHandler.HandleRequirementAsyn c (настраиваемая политика)?