问题描述
我在服务器端渲染中使用了blazor,我想做自己的AuthenticationStateProvider,但这是行不通的,我也不知道为什么.
I use blazor with server side render and I want to do my own AuthenticationStateProvider, but it's not work and I do not know why.
我在公共类LocalAuthenticationStateProvider:AuthenticationStateProvider 中的ovveride方法:
My ovveride method in public class LocalAuthenticationStateProvider : AuthenticationStateProvider:
public async override Task<AuthenticationState> GetAuthenticationStateAsync()
{
if (await _storageService.ContainKeyAsync("User"))
{
var userInfo = await _storageService.GetItemAsync<LocalUserInfo>("User");
var claims = new[]
{
new Claim("Email", userInfo.Email),
new Claim("FirstName", userInfo.FirstName),
new Claim("LastName", userInfo.LastName),
new Claim("AccessToken", userInfo.AccessToken),
new Claim(ClaimTypes.NameIdentifier, userInfo.Id),
};
var identity = new ClaimsIdentity(claims, "BearerToken");
var user = new ClaimsPrincipal(identity);
var state = new AuthenticationState(user);
NotifyAuthenticationStateChanged(Task.FromResult(state));
return state;
}
return new AuthenticationState(new ClaimsPrincipal());
}
我的登录页面:
@inject AuthenticationStateProvider authenticationStateProvider
await storageService.SetItemAsync("User", userInfo);
await authenticationStateProvider.GetAuthenticationStateAsync();
navigationManager.NavigateTo("/");
我的Startup.cs
My Startup.cs
services.AddAuthentication();
services.AddAuthorization();
services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, LocalAuthenticationStateProvider>();
我的 Index.razor 用于检查身份验证.这总是未经授权的
My Index.razor for check auth. This always NotAuthorized
<AuthorizeView>
<Authorized>
<h1>Hi! @context.User.FindFirst("FirstName").Value</h1>
</Authorized>
<NotAuthorized>
<RadzenButton Text="login" Click="GoToRegister"></RadzenButton>
</NotAuthorized>
<Authorizing>
<h1>Authentication in progress</h1>
<p>Only visible while authentication is in progress.</p>
</Authorizing>
这是怎么了?
推荐答案
在您的登录页面中,您应该注入LocalAuthenticationStateProvider
In your Login page you should inject LocalAuthenticationStateProvider
@inject LocalAuthenticationStateProvider LocalAuthStateProvider
这样做之后:
await storageService.SetItemAsync("User", userInfo);
我猜
存储用户的信息,让CascadingAuthenticationState
之类的订户知道Authentication状态已更改.这样做是这样的:
which I guess, storing the user's information, let subscribers, such as the CascadingAuthenticationState
, know that the Authentication state has been changed.This is done so:
LocalAuthStateProvider.NotifyAuthenticationStateChanged();
您的自定义AuthenticationStateProvider应该类似于以下内容:
Your custom AuthenticationStateProvider should be like the following:
public async override Task<AuthenticationState> GetAuthenticationStateAsync()
{
ClaimsIdentity identity;
if (await _storageService.ContainKeyAsync("User"))
{
var userInfo = await _storageService.GetItemAsync<LocalUserInfo>
("User");
var claims = new[]
{
new Claim("Email", userInfo.Email),
new Claim("FirstName", userInfo.FirstName),
new Claim("LastName", userInfo.LastName),
new Claim("AccessToken", userInfo.AccessToken),
new Claim(ClaimTypes.NameIdentifier, userInfo.Id),
};
identity = new ClaimsIdentity(claims );
}
else
{
identity = new ClaimsIdentity();
}
return await Task.FromResult(new AuthenticationState(new
ClaimsPrincipal(identity)));
}
public void NotifyAuthenticationStateChanged()
{
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
您的Startup类应该是这样的:
And your Startup class should be like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddAuthorization();
// services.AddAuthorizationCore();
services.AddScoped<LocalAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<LocalAuthenticationStateProvider>());
}
希望这对您有帮助...
Hope this helps...
这篇关于为什么我的身份验证状态提供程序不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!