问题描述
我正在使用Blazor Wasm编写SPA.我使用了标准模板,并在服务器中托管了用户帐户,该服务器也创建了服务器应用程序.到目前为止,一切都很好.我要补充一点,我使用的是.Net5 RC2,但我认为这不是我的问题.
I am writing an SPA using Blazor Wasm. I have used the standard template and included user accounts hosted in the server which has created a server app as well. This is all fine so far.I would add that I am using .Net5 RC2 but I don't think that is my issue here.
我想在服务器以及客户端应用程序中有一些普通"的剃须刀页面.用户帐户身份服务器创建了文件夹结构/Areas/Identity/Pages/....我添加了/Areas/Management/Pages/Admin/Test.cshtml和Test.cshtml.cs这些是非常简单的测试文件...
I want to have some 'normal' razor pages in the server as well as those in the client app. The user accounts Identity server created the folder structure /Areas/Identity/Pages/....I have added /Areas/Management/Pages/Admin/Test.cshtml and Test.cshtml.csThese are very simple test files...
编辑-我已对其进行了编辑,以反映@enet提出的问题.
EDIT - I have edited this to reflect the questions asked by @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,则该页面将完全不呈现.(此页面不起作用!-来自浏览器的消息).因此,根据我的研究,剃刀页面授权约定
I want to see the page say either User is admin, or User is not admin.In Case A : If the [Authorize] is removed, the page will load, but will always show that the user is Not authorised. So the page is being rendered and the simple test yields the 'else' case..In case B : the page will not render at all. (This page isn't working! - message from the browser). So, from my research, in this:Razor Pages Authorization Conventions
我从这里更改了startup.cs:
I changed my startup.cs from this:
services.AddRazorPages();
对此:
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeAreaFolder("Management", "/Admin");
});
***我已经取出上面的内容并将其重置为原来的状态
*** I have taken out the above and reset it to how it was ***
当我这样做时,无论是否在.cs文件中使用[Authorize],都会产生与情况B相同的结果.当您阅读文档时,我猜这是有道理的.
When I do that, the same result as case B ensues, with or without the [Authorize] in the .cs file. Which makes sense I guess when you read the docs.
所以我想我需要回传某种形式的授权令牌,或者?
So I guess I need to be passing back some form of Authorization token back, or ?
身份"页面不需要任何授权,因此这不是问题.我的配置服务如下:
The Identity pages don't require any authorization so it isn't an issue there.My configure services looks like this:
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"事件:
*** The navigation to the server page works from a button in NavMenu firing an 'onclick' event to this:
private void ServerPageTest()
{
Navigation.NavigateTo("/Management/Admin/Test", true);
}
我有种感觉,我在启动时会缺少一些选择.
I have a feeling I am missing some options in my startup, any thoughts..
推荐答案
我认为答案是我
更改Startup.cs文件,其中包含:
Changing the Startup.cs file, where we have:
services.AddAuthentication();
我将其更改为:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
})
然后,这将允许服务器通过身份验证来提供剃须刀页面.
This then allows the server to serve up razor pages, with authentication.
它还有另一个副作用,那就是更改声明在服务器上的感知方式,并使所有API控制器能够以更传统的控制器方式工作.我会解释.我还有一个带有API端点"AddUpdateUser"的"ApplicationUserController",它的功能与罐子上说的一样.
It also had another side effect of changing how the claims are perceived back at the server, and causes any API controllers to be able to work in a more traditional controller manner. I'll explain. I also have an 'ApplicationUserController' with an api endpoint 'AddUpdateUser', which does what it says on the tin.
我有以下代码可以检查已登录的用户:
I had this code to check the logged in user:
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.所以我不得不求助于带有以下代码的声明中的userID:
But it was always returning null. and so I had to resort to finding the userID from the claims with this code:
string loggedinUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApplicationUser loggedinUser = _context.Users.Find(loggedinUserId);
我还必须搜索如何执行此操作.当然是在这个很棒的网站上找到的.
I'd had to search how to do this also. Found it on this great site of course.
但是在启动时添加了两行,破坏了该代码并使原始代码正常工作.我想我知道现在为什么会这样,对于人们来说说阅读文档"非常好,但是有时候它实在是太压倒性了.
But adding the two lines to the start up, the broke this code and made the original code work. I think I understand why now, and its all very well for folks to say 'read the documentation' but sometimes it's just too overwhelming.
无论如何,我希望这对某些人有帮助.
Anyway, I hope this helps some people.
这篇关于在Blazor WebAssemby应用程序中授权普通Razor页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!