将Blazor Wasm连接到Identity Server 4-注册和帐户管理链接不起作用



希望有人能引导我朝着正确的方向前进,因为我已经为此工作了一段时间。

我已经在.Net Core中创建了一个Blazor WASM。但是,我不想在服务器(API)项目中使用标识,而是想使用托管在不同项目中的identity Server进行身份验证(这样我就可以使用独立的identity Server)。

我创建了一个Identity Server 4项目,还构建了Identity Razor页面(这样我就可以完整地进行注册、帐户管理、密码恢复等操作),而不是Identity Server生成的3个左右的基本页面。

在我的Blazor客户端项目中,我在Main方法中添加了以下内容:

{
// Bind to the oidc section in the appsettings.
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = JwtClaimTypes.Role;
})

此外,在我的appsettings文件中,我有以下oidc部分:

"oidc": {
"Authority": "https://localhost:5001",
"ClientId": "ProjectAllocation.Client",
"DefaultScopes": [
"openid",
"profile",
"roles",
"offline_access"
],
"PostLogoutRedirectUri": "/",
"ResponseType": "code"
}
}

在Identity Server中,在Startup ConfigureServices中,我正在重定向登录\注销以使用脚手架标识区域中的页面:

var builder = services.AddIdentityServer(options =>
{
...
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
options.Authentication = new IdentityServer4.Configuration.AuthenticationOptions
{
CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
CookieSlidingExpiration = true
};
})

现在登录和注销工作了,我似乎在客户端中获得了正确的令牌数据;我还没有在服务器端实现API。

我的问题是来自客户端项目的注册和帐户管理链接不起作用。如果您将使用带有集成身份服务器的VS中的模板,则您可以单击客户端应用程序中的注册链接,并进入"身份"区域中的"帐户\注册"页面;一旦你登录,你就可以点击";你好"链接,并被带到"身份"区域中的"帐户"管理。

然而,这在我的情况下不起作用。如果我从浏览器直接导航到这些区域,那么它就可以工作(即:浏览到https://localhost:5001/Identity/Account/Register:它起作用)。当我点击客户端应用程序中的"注册"按钮时,它会使用以下链接重新加载应用程序:https://localhost:44395/?returnUrl=%2Fauthentication%2Flogin:即使Identity Server中的"注册"页面被标记为允许匿名访问,看起来应用程序似乎被要求登录。

我真的很困惑为什么这不起作用。我不知道Blazor项目中的哪些设置设置了要通过RemoteAuthenticatorView导航到的链接。我正在考虑更换注册按钮,这样它就不再通过RemoteAuthenticatorView导航,而是使用直接指向Identity Server注册页面的常规链接,但我不确定这意味着什么;而且,我不能让它正常工作,这真的很烦人。

我甚至尝试更改注册页面的路径,使Identity Server 4:中启动文件中的ConfigureServices代替Identity/Account/register

services.AddRazorPages(options => {
options.Conventions.AddAreaPageRoute("Identity", "/Account/Register", "Account/Register");
});

在浏览器中工作(https://localhost:5001/Account/Register),但它仍然无法从WASM Blazor客户端运行。

有什么想法吗?

谢谢,Raz

我将把这个留在这里,以防其他人偶然发现。我已经查看了Blazor WASM代码,对于注册和帐户管理,它使用NavigationManager导航到AuthenticationPaths的RemoteRegisterPath和RemoteProfilePath属性中提供的路径。

尽管有一些奇怪的原因,但看起来您无法导航到外部url:NavigationManager将忽略提供的基地址,并使用项目的基地址。所以,尽管我试图提供一个地址https://localhost:5001/Identity/Account/Register,应用程序实际导航到https://localhost:44395/Identity/Account/Register.

作为一种变通方法,我创建了一个名为Account的控制器,它有两个方法Register和Manage,将重定向到Identity Server的地址。因此,Blazor客户端将调用Blazor API服务器项目中帐户控制器中的相应方法,该方法将重定向到相应的Identity server页面。

我修改了Blazor Client项目中Main方法中对AddOidcAuthentication()的调用:

builder.Services.AddOidcAuthentication(options =>
{
// Bind to the oidc section in the appsettings.

builder.Configuration.Bind("oidc", options.ProviderOptions);
options.AuthenticationPaths.RemoteRegisterPath = "Account/Register";
options.AuthenticationPaths.RemoteProfilePath = "Account/Manage";
options.UserOptions.RoleClaim = JwtClaimTypes.Role;
})

我还在Blazor API服务器项目的Controllers文件夹中创建了一个AccountController:

[Route("[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
[AllowAnonymous]
[HttpGet("Register")]
public IActionResult Register(string returnUrl)
{
return Redirect(@"https://localhost:5001/Identity/Account/Register?returnUrl=https://localhost:44395/" + returnUrl);
}
[AllowAnonymous]
[HttpGet("Manage")]
public IActionResult Manage(string returnUrl)
{
return Redirect(@"https://localhost:5001/Identity/Account/Manage?returnUrl=https://localhost:44395/" + returnUrl);
}
}

授权Manage方法可能是个好主意。此外,returnUrl可能需要一些额外的参数(至少对于login\logout有更多的参数)。

此外,我需要对Identity Server项目中搭建的Identity文件进行一些小的更改,以允许重定向到非本地路径。

有些地方可以改进,这确实感觉像是一次黑客攻击,但解决方案目前有效,我找不到更好的替代方案。

标准IdentityServer4项目模板不包括任何用于注册用户的页面,您必须在IdentityServer 4中开发这些页面。要获得用户注册页面,您可以尝试以下项目/产品之一:

  • 一个ASP。NET Core IdentityServer4带有Bootstrap 4和本地化的标识模板
  • AdminUI

最新更新