目标:
如果用户没有登录,我想要一种登陆页面(基本上所有其他页面都应该被锁定,而不需要所有页面上的 [Authorize]
属性)。
设置:
代码:
我已经重写了 MainLayout.razor
以将所有未授权的请求重定向到我的重定向处理程序
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
我的 RedirectToLogin.razor
包含名为 Index.razor
的登录页面和用于身份验证请求的 RemoteAuthenticatorView
@inject NavigationManager Navigation
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@if (!string.IsNullOrEmpty(action))
{
<RemoteAuthenticatorView Action="@action" />
}
else
{
<div>
Landing page...<br />
<a href="/authentication/Login">Login</a><br />
<a href="/authentication/Register">register</a>
</div>
}
我的 RedirectToLogin.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();
}
}
}
}
问题:
整个系统基本上适用于所有身份验证请求,登录回调除外。
它仍然显示着陆页,而不是加载授权视图。
您需要刷新页面或再次点击登录按钮才能重定向到授权视图。
我尝试在导航更改时使用 url 中的登录回调或用户获得授权时手动导航用户,但似乎没有任何效果。
您知道为什么会出现这种行为和/或如何解决这个问题吗?
如果有更简单的方法来实现我的目标,请发表评论。我在网上没有找到任何东西,我尽力了。
答案 0 :(得分:1)
问题是您将与身份验证相关的所有内容传递到此登录页面。您需要为您要执行的操作设置两个单独的页面,一个用于未授权用户的登陆页面,另一个用于授权用户。
要更改此设置,您需要更新 Program.cs
文件并在 AuthenticationPaths
下设置 builder.Services.AddApiAuthorization
。举个例子:
builder.Services.AddApiAuthorization(options =>
{
options.AuthenticationPaths.LogInPath = "auth/login";
options.AuthenticationPaths.LogInCallbackPath = "auth/login-callback";
options.AuthenticationPaths.LogInFailedPath = "auth/login-failed";
options.AuthenticationPaths.LogOutPath = "auth/logout";
options.AuthenticationPaths.LogOutCallbackPath = "auth/logout-callback";
options.AuthenticationPaths.LogOutFailedPath = "auth/logout-failed";
options.AuthenticationPaths.LogOutSucceededPath = "auth/logged-out";
options.AuthenticationPaths.ProfilePath = "auth/profile";
options.AuthenticationPaths.RegisterPath = "auth/register";
options.AuthenticationPaths.RemoteProfilePath = "/profile";
options.AuthenticationPaths.RemoteRegisterPath = "/register";
});
然后是 Authentication.razor
页面:
@page "/auth/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action">
<LoggingIn></LoggingIn>
<CompletingLoggingIn></CompletingLoggingIn>
<LogInFailed>Failed to log in.</LogInFailed>
<LogOut></LogOut>
<LogOutFailed>Failed to log out.</LogOutFailed>
<CompletingLogOut></CompletingLogOut>
<LogOutSucceeded><RedirectToLogin ReturnUrl="Dashboard"/></LogOutSucceeded>
<UserProfile></UserProfile>
<Registering></Registering>
</RemoteAuthenticatorView>
@code{
[Parameter] public string Action { get; set; }
}
有关 RemoteAuthenticatorView
的更多信息,请查看此 Microsoft 文档:https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-5.0#customize-app-routes