为什么我的身份验证状态提供程序不起作用?
Why my Authentication State Provider not work?
我将 blazor 与服务器端渲染一起使用,我想做我自己的 AuthenticationStateProvider,但它不起作用,我不知道为什么。
我在 public class 中的 ovveride 方法 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
services.AddAuthentication();
services.AddAuthorization();
services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, LocalAuthenticationStateProvider>();
我的 Index.razor 用于检查授权。这总是 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
@inject LocalAuthenticationStateProvider LocalAuthStateProvider
完成后:
await storageService.SetItemAsync("User", userInfo);
我猜,存储用户的信息,让订阅者,例如 CascadingAuthenticationState
,知道身份验证状态已更改。
这样做是这样的:
LocalAuthStateProvider.NotifyAuthenticationStateChanged();
您的自定义 AuthenticationStateProvider 应如下所示:
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 class 应该是这样的:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddAuthorization();
// services.AddAuthorizationCore();
services.AddScoped<LocalAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<LocalAuthenticationStateProvider>());
}
希望这对您有所帮助...
我将 blazor 与服务器端渲染一起使用,我想做我自己的 AuthenticationStateProvider,但它不起作用,我不知道为什么。
我在 public class 中的 ovveride 方法 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
services.AddAuthentication();
services.AddAuthorization();
services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, LocalAuthenticationStateProvider>();
我的 Index.razor 用于检查授权。这总是 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
@inject LocalAuthenticationStateProvider LocalAuthStateProvider
完成后:
await storageService.SetItemAsync("User", userInfo);
我猜,存储用户的信息,让订阅者,例如 CascadingAuthenticationState
,知道身份验证状态已更改。
这样做是这样的:
LocalAuthStateProvider.NotifyAuthenticationStateChanged();
您的自定义 AuthenticationStateProvider 应如下所示:
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 class 应该是这样的:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddAuthorization();
// services.AddAuthorizationCore();
services.AddScoped<LocalAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<LocalAuthenticationStateProvider>());
}
希望这对您有所帮助...