繁体   English   中英

.net Blazor 认证机制

[英].net Blazor authentication mechanism

经过数周的研究,我仍然陷入困境......

我的目标是:在 Windows 身份验证之后,调用自定义应用程序授权过程,该过程将为Blazor提供 ClaimsPrincipal 以执行基于角色的授权。

在我的 Blazor 的 program.cs 中,我使用的是 Windows 身份验证,并有一个事件对身份验证“做出反应”:

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

我还有一个自定义的AuthenticationStateProvider ,它具有吸收ClaimsPrincipal的方法。

如果我在 WhenAuthenticated() 事件中执行自定义身份验证,如何调用 AuthenticationStateProvider?

PS我不想使用微软的MVC认证model,因为我们已经建立了自己的model。

我想我明白你想要做什么,所以这是我回答它的机会。

我使用了标准服务器模板和 Windows 身份验证作为我的基础。 完整的VS解决方案在这里: https://github.com/ShaunCurtis/SO73545707

这一切都在AuthenticationStateProvider中。 矿:

  1. 继承自ServerAuthenticationStateProvider而不是AuthenticationStateProvider ,因此我们可以调用基本方法并获取 state。
  2. 将具有相关信息的ClaimsIdentity添加到现有ClaimsPrincipal
  3. 根据更新的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());
        }
    }
}

服务注册如下所示:

// 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>();

我在标准页面中添加了一些Authorize属性来测试它。

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

暂无
暂无

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

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