我还添加了以下代码来强制它,但即使没有调用onIntitializedAsync函数。
protected override async Task OnInitializedAsync()
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
if (!authState.User.Identity.IsAuthenticated)
{
NavigationManager.NavigateTo("login");
}
}
该组件在INIT函数上具有简单的导航管理器,该函数将路由到 /login。
似乎在每次更新后我都必须重新学习闪耀。
Edit1我正在使用builder.services.addcascadingauthenticationstate();在程序文件中而不是周围的路由器
中
我还添加了以下代码以强迫它,但是 IntitializedAsync函数甚至都没有被称为。 如果您的
RedirectToLogin
"/index"
被Authentication Middleware bess当您添加与身份验证相关的服务
时,您可能会尝试配置重定向路径
或添加一个中间件:
app.Use(async (context,next) =>
{
await next.Invoke();
if(context.Response.StatusCode==StatusCodes.Status401Unauthorized)
{
context.Response.Redirect("{your login path with return url}");
}
});
在身份验证中间软件之前
在查看Blazor Web应用程序9的身份单个用户模板(使用服务器/全局渲染模式)之后,我设法使JWT auth工作! 步长1-program.cs
身份验证 /授权所需的所有代码如下:
也要添加:
app.UseAuthentication();
app.UseAuthorization();
我已经使用blazoredlocalstorage
存储我的令牌,但是可以使用其他任何东西
public class CustomAuthenticationStateProvider(ILocalStorageService localStorageService) : AuthenticationStateProvider
{
private readonly ILocalStorageService _localStorage = localStorageService;
private const string TokenKey = "authToken";
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
try
{
var token = await _localStorage.GetItemAsync<string>(TokenKey);
if (string.IsNullOrWhiteSpace(token))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
var claims = ParseClaimsFromJwt(token);
var identity = new ClaimsIdentity(claims, "jwt");
var user = new ClaimsPrincipal(identity);
return new AuthenticationState(user);
}
catch (JSException ex)
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
catch (Exception)
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
}
public void NotifyUserAuthentication(string token)
{
var claims = ParseClaimsFromJwt(token);
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt"));
var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
NotifyAuthenticationStateChanged(authState);
}
public void NotifyUserLogout()
{
var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
var authState = Task.FromResult(new AuthenticationState(anonymousUser));
NotifyAuthenticationStateChanged(authState);
}
private static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwt);
return token.Claims;
}
}
步骤3-修改App.Razor文件 不知道这实际上是什么,但我猜这是必需的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["BlazorApp1-Jwt.styles.css"]" />
<ImportMap />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="PageRenderMode" />
</head>
<body>
<Routes @rendermode="PageRenderMode" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? PageRenderMode =>
HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}
步骤4-配置routes.razor文件
@using Microsoft.AspNetCore.Components.Authorization
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
notfound属性,因为它不再使用Blazor Web应用程序8和9
使用 步骤5-redirecttologin
创建一个组件,该组件将用户试图访问安全页面当用户尝试登录页面
@inject NavigationManager NavigationManager
@code {
protected override void OnInitialized()
{
NavigationManager.NavigateTo("login", forceLoad: true);
}
}
aquire您的令牌,将其保存在LocalStorage中(或者您需要处理)并通知AuthstateProvider
((CustomAuthenticationStateProvider)AuthenticationStateProvider).NotifyUserAuthentication(token);
在您想要的任何页面上使用
授权属性
注:我不是专家。这就是我的工作方式。如果我在这里写的是可怕的代码,请写入 /重定向到更好的解决方案。