[英].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:矿:
ServerAuthenticationStateProvider
rather than AuthenticationStateProvider
so we can call the base method and get the state.ServerAuthenticationStateProvider
而不是AuthenticationStateProvider
,因此我们可以调用基本方法并获取 state。ClaimsIdentity
with the relevant information to the existing ClaimsPrincipal
.ClaimsIdentity
添加到现有ClaimsPrincipal
。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.