C# 非授权用户的Blazor登录页
目标:C# 非授权用户的Blazor登录页,c#,authentication,routes,blazor,blazor-webassembly,C#,Authentication,Routes,Blazor,Blazor Webassembly,目标: 如果用户未登录,我希望有一种登录页面(基本上所有其他页面都应锁定,而无需在所有页面上使用[Authorize]属性) 设置: 布拉佐·瓦斯姆 ASP.NET托管(具有IdentityServer授权) 代码: 我已经重写了MainLayout.razor,将所有未授权的请求重定向到我的重定向处理程序 <NotAuthorized> <RedirectToLogin /> </NotAuthorized> MyRedirectToLog
如果用户未登录,我希望有一种登录页面(基本上所有其他页面都应锁定,而无需在所有页面上使用
[Authorize]
属性)
设置:
- 布拉佐·瓦斯姆
- ASP.NET托管(具有IdentityServer授权)
代码:
我已经重写了
MainLayout.razor
,将所有未授权的请求重定向到我的重定向处理程序
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
MyRedirectToLogin.razor.cs
会侦听位置更改并将身份验证请求转发到RemoteAuthenticatorView
public partial class RedirectToLogin : IDisposable
{
[CascadingParameter] private Task<AuthenticationState> AuthenticationStateTask { get; set; }
[Inject] private NavigationManager NavigationManager { get; set; }
string action = "";
protected override async Task OnInitializedAsync()
{
NavigationManager.LocationChanged += LocationChanged;
}
public void Dispose()
{
NavigationManager.LocationChanged -= LocationChanged;
}
async void LocationChanged(object sender, LocationChangedEventArgs e)
{
action = "";
var authenticationState = await AuthenticationStateTask;
if (authenticationState?.User?.Identity is not null)
{
var url = Navigation.ToBaseRelativePath(Navigation.Uri);
if (!authenticationState.User.Identity.IsAuthenticated)
{
if (url == "authentication/logged-out")
{
NavigationManager.NavigateTo("", true);
return;
}
if (url.Contains("authentication"))
{
var index = url.IndexOf("authentication") + 15;
if (url.Contains("?"))
action = url.Substring(index, url.IndexOf('?') - index);
else
action = url.Substring(index);
}
this.StateHasChanged();
}
}
}
}
public部分类重定向到登录:IDisposable
{
[CascadingParameter]专用任务AuthenticationStateTask{get;set;}
[注入]专用导航管理器导航管理器{get;set;}
字符串动作=”;
受保护的重写异步任务OnInitializedAsync()
{
NavigationManager.LocationChanged+=LocationChanged;
}
公共空间处置()
{
NavigationManager.LocationChanged-=LocationChanged;
}
异步void LocationChanged(对象发送方,LocationChangedEventArgs e)
{
action=“”;
var authenticationState=等待AuthenticationStateTask;
if(authenticationState?.User?.Identity不为空)
{
var url=Navigation.ToBaseRelativePath(Navigation.Uri);
如果(!authenticationState.User.Identity.IsAuthenticated)
{
如果(url==“身份验证/注销”)
{
NavigationManager.NavigateTo(“,true);
返回;
}
if(url.Contains(“身份验证”))
{
var index=url.IndexOf(“身份验证”)+15;
if(url.Contains(“?”)
action=url.Substring(index,url.IndexOf(“?”)-index);
其他的
action=url.Substring(索引);
}
此.StateHasChanged();
}
}
}
}
问题:
整个系统基本上可以处理所有身份验证请求,但登录回调除外 它不再加载授权视图,而是显示登录页。 您需要刷新页面或再次单击登录按钮以重定向到授权视图 我尝试在url中使用登录回调进行导航更改时手动导航用户,或者在用户获得授权时手动导航用户,但似乎没有任何效果 你知道为什么会发生这种行为和/或如何解决吗
如果有更简单的方法来实现我的目标,请发表评论。我在网上找不到任何东西,并尽了最大努力。问题是您正在将与身份验证相关的所有信息传递到此登录页。你需要有两个独立的页面来完成你的任务,一个是未授权用户的登录页面,另一个是授权用户的登录页面 要更改此设置,您需要更新
Program.cs
文件,并在builder.Services.addapiaauthorization
下设置authenticationpath
。下面是一个例子:
builder.Services.AddApiAuthorization(选项=>
{
options.authenticationpath.LogInPath=“auth/login”;
options.authenticationpath.LogInCallbackPath=“auth/login回调”;
options.authenticationpath.LogInFailedPath=“auth/login失败”;
options.authenticationpath.LogOutPath=“auth/logout”;
options.authenticationpath.LogOutCallbackPath=“auth/logout callback”;
options.authenticationpath.LogOutFailedPath=“auth/logout失败”;
options.authenticationpath.LogOutSucceededPath=“auth/logged-out”;
options.authenticationpath.ProfilePath=“auth/profile”;
options.authenticationpath.RegisterPath=“auth/register”;
options.authenticationPath.RemoteProfilePath=“/profile”;
options.AuthenticationPath.RemoteRegisterPath=“/register”;
});
然后进入Authentication.razor
页面:
@page”/auth/{action}
@使用Microsoft.AspNetCore.Components.WebAssembly.Authentication
登录失败。
无法注销。
@代码{
[参数]公共字符串操作{get;set;}
}
有关RemoteAuthenticatorView
的更多信息,请查看以下Microsoft文档:
在该部分下方:成功登录后,您是否从
Login.razor
更改了导航?如果您不知道,由于登录位置保持不变,给定的LocationChanged
回调不应工作。我认为,这就是为什么你需要重新点击登录按钮或刷新页面。
public partial class RedirectToLogin : IDisposable
{
[CascadingParameter] private Task<AuthenticationState> AuthenticationStateTask { get; set; }
[Inject] private NavigationManager NavigationManager { get; set; }
string action = "";
protected override async Task OnInitializedAsync()
{
NavigationManager.LocationChanged += LocationChanged;
}
public void Dispose()
{
NavigationManager.LocationChanged -= LocationChanged;
}
async void LocationChanged(object sender, LocationChangedEventArgs e)
{
action = "";
var authenticationState = await AuthenticationStateTask;
if (authenticationState?.User?.Identity is not null)
{
var url = Navigation.ToBaseRelativePath(Navigation.Uri);
if (!authenticationState.User.Identity.IsAuthenticated)
{
if (url == "authentication/logged-out")
{
NavigationManager.NavigateTo("", true);
return;
}
if (url.Contains("authentication"))
{
var index = url.IndexOf("authentication") + 15;
if (url.Contains("?"))
action = url.Substring(index, url.IndexOf('?') - index);
else
action = url.Substring(index);
}
this.StateHasChanged();
}
}
}
}