简体   繁体   English

.net Blazor 认证机制

[英].net Blazor authentication mechanism

After weeks of research, I am still running into the wall....经过数周的研究,我仍然陷入困境......

My objective is: After the Windows authentication, invoke a custom application authorization process which will provide the ClaimsPrincipal for Blazor to perform role-based authorization.我的目标是:在 Windows 身份验证之后,调用自定义应用程序授权过程,该过程将为Blazor提供 ClaimsPrincipal 以执行基于角色的授权。

In my Blazor's program.cs, I am using the Windows Authentication and have an Event to "react" to the authentication:在我的 Blazor 的 program.cs 中,我使用的是 Windows 身份验证,并有一个事件对身份验证“做出反应”:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
            .AddNegotiate(
              options => { 
                options.Events = 
                  new CMAPNegotiateEvents(builder.Environment);
              });

I also have a custom AuthenticationStateProvider with a method to absorb the ClaimsPrincipal .我还有一个自定义的AuthenticationStateProvider ,它具有吸收ClaimsPrincipal的方法。

If I perform the custom authentication in the WhenAuthenticated() event, how do I invoke the AuthenticationStateProvider?如果我在 WhenAuthenticated() 事件中执行自定义身份验证,如何调用 AuthenticationStateProvider?

PS I don't want to use the Microsoft's MVC authentication model, because we already have our own model established. PS我不想使用微软的MVC认证model,因为我们已经建立了自己的model。

I think I understand what you are trying to do so here's my shot at answering it.我想我明白你想要做什么,所以这是我回答它的机会。

I've used the standard Server template with Windows Authentication as my base.我使用了标准服务器模板和 Windows 身份验证作为我的基础。 The complete VS solution is here: https://github.com/ShaunCurtis/SO73545707完整的VS解决方案在这里: https://github.com/ShaunCurtis/SO73545707

It's all in the AuthenticationStateProvider .这一切都在AuthenticationStateProvider中。 Mine:矿:

  1. Inherits from ServerAuthenticationStateProvider rather than AuthenticationStateProvider so we can call the base method and get the state.继承自ServerAuthenticationStateProvider而不是AuthenticationStateProvider ,因此我们可以调用基本方法并获取 state。
  2. Adds a ClaimsIdentity with the relevant information to the existing ClaimsPrincipal .将具有相关信息的ClaimsIdentity添加到现有ClaimsPrincipal
  3. Returns a new AuthenticationState based on the updated ClaimsPrincipal .根据更新的ClaimsPrincipal返回一个新的AuthenticationState
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using Microsoft.AspNetCore.Connections.Features;
using System.Security.Claims;

namespace SO73545707.Data
{
    // Inherit from ServerAuthenticationStateProvider 
    public class MyAuthenticationStateProvider : ServerAuthenticationStateProvider
    {
        public async override Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            // Call the base to get the AuthState and the user provided in the Security Headers by the server
            var authstate = await base.GetAuthenticationStateAsync();
            var user = authstate.User;

            if (user is not null)
            {
                // Do whatever you want here to retrieve the additional user information you want to
                // include in the ClaimsPrincipal - probably some form of Identity Service
                
                // Construct a ClaimsIdentity instance to attach to the ClaimsPrincipal
                var myIdentity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, "User") });
                // Add it to the existing ClaimsPrincipal
                user.AddIdentity(myIdentity);
            }

            // construct a new state with the updated ClaimsPrincipal
            // - or an empty one of you didn't get a user in the first place
            // All the Authorization components and classes will now use this ClaimsPrincipal 
            return new AuthenticationState(user ?? new ClaimsPrincipal());
        }
    }
}

The service registration looks like this:服务注册如下所示:

// Add services to the container.
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// must be after AddServerSideBlazor
builder.Services.AddScoped<AuthenticationStateProvider, MyAuthenticationStateProvider>();
builder.Services.AddSingleton<WeatherForecastService>();

I've added some Authorize attributes to the standard pages to test it.我在标准页面中添加了一些Authorize属性来测试它。

@attribute [Authorize(Roles = "User")]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM