context.User.Identity.Name недоступен в Blazor ASP. NET Core размещен - PullRequest
0 голосов
/ 10 июля 2020

Я создал 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

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 (настраиваемая политика)?

...