我正在使用Blazor Wasm编写SPA。我使用了标准模板,并在服务器中托管了用户帐户,该服务器也创建了服务器应用程序。到目前为止一切都很好。 我要补充一点,我使用的是.Net5 RC2,但我认为这不是我的问题。
我想在服务器以及客户端应用程序中有一些“普通”剃须刀页面。用户帐户身份服务器创建了文件夹结构/ Areas / Identity / Pages /...。 我添加了/Areas/Management/Pages/Admin/Test.cshtml和Test.cshtml.cs 这些是非常简单的测试文件...
编辑-我已对其进行了编辑,以反映@enet提出的问题。
剃刀文件:
@page
@model ProjName.Server.Areas.Management.Pages.Admin.TestModel
<h1>Test Page</h1>
@if (User.Identity.IsAuthenticated)
{
@if (User.IsInRole("Administrator"))
{
<h2>User is Admin</h2>
}
else
{
<h2>User is not an admin</h2>
}
}
else
{
<h2>User is Not Authenticated</h2>
}
@{
}
.CS文件:
namespace ProjName.Server.Areas.Management.Pages.Admin
{
[Authorize] <<<--- See case B.
public class TestModel : PageModel
{
public void OnGet()
{
}
}
}
我想看到页面上显示“用户是管理员”或“用户不是管理员”。 在情况A中:如果删除了[授权],则将加载该页面,但始终会显示该用户未被授权。因此,正在渲染页面,并且简单的测试产生了“ else”情况。 如果是B,则该页面将完全不呈现。 (此页面不起作用!-来自浏览器的消息)。因此,根据我的研究, Razor Pages Authorization Conventions
我从这里更改了startup.cs:
services.AddRazorPages();
对此:
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeAreaFolder("Management", "/Admin");
});
***我已取出上面的内容,并将其重置为原来的状态
执行此操作时,无论是否在.cs文件中使用[Authorize],都会产生与情况B相同的结果。当您阅读文档时,我猜这很有道理。
所以我想我需要回传某种形式的授权令牌,或者?
“身份”页面不需要任何授权,因此这不是问题。 我的配置服务如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<RGDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<RGDbContext>();
// This was put in to try to sort this https://github.com/dotnet/AspNetCore.Docs/issues/17517
//services.Configure<IdentityOptions>(options =>
// options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, RGDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
//services.AddRazorPages();
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeAreaFolder("Management", "/Admin");
});
.... more of my own stuff...
***通过NavMenu中的按钮向服务器页面导航可触发对此事件的“ onclick”事件:
private void ServerPageTest()
{
Navigation.NavigateTo("/Management/Admin/Test", true);
}
我有种感觉,我在启动时缺少一些选择。
答案 0 :(得分:0)
我有答案,我想...
更改Startup.cs文件,其中包含:
services.AddAuthentication();
我将其更改为:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
})
然后,这将允许服务器通过身份验证来提供剃须刀页面。
它还有另一个副作用,那就是更改声明在服务器上的感知方式,并使所有API控制器能够以更传统的控制器方式工作。我会解释。我还有一个带有API端点“ AddUpdateUser”的“ ApplicationUserController”,它的功能与罐子上说的一样。
我有以下代码可以检查已登录的用户:
public async Task<ActionResult<ApplicationUserDTO>> AddUpdateUser(ApplicationUserDTO sentUser)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Get the logged in user.
// This line should work but doesnt and I dont know why.
ApplicationUser loggedinUserX = await _userManager.GetUserAsync(User).ConfigureAwait(false);
但是它总是返回null。因此,我不得不使用以下代码从声明中找到用户ID:
string loggedinUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApplicationUser loggedinUser = _context.Users.Find(loggedinUserId);
我还必须搜索如何执行此操作。当然是在这个很棒的网站上找到的。
但是在启动时添加了两行,破坏了该代码并使原始代码正常工作。我想我知道现在为什么会这样,对于人们来说说“阅读文档”非常好,但是有时候它实在是太压倒性了。
无论如何,我希望这对某些人有帮助。