用户授权 - 为用户分配授权策略 .Net Core 3.1
Posted
技术标签:
【中文标题】用户授权 - 为用户分配授权策略 .Net Core 3.1【英文标题】:Authorization of user - Assigning user a Authorization Policy .Net Core 3.1 【发布时间】:2021-10-23 23:34:15 【问题描述】:因此,当此代码运行时,用户获得了身份验证,我看到他们有我提供给他们的相关声明。但是,他们无权查看任何页面,因为他们没有正确的 AuthorizationPolicy。我认为给他们“Court User”的角色并对其进行身份验证会给他们默认的“Court_Users”AuthorizationPolicy,因为这符合要求,但它不能这样工作。
当用户通过身份验证后,如何为他们分配符合要求的授权策略?
启动页面:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
options.LoginPath = "/Shared/login";
options.AccessDeniedPath = "/Shared/login";
);
services.AddRazorPages().AddRazorPagesOptions(options =>
options.Conventions.AuthorizeFolder("/NonCourt_Users","Non Court User");
options.Conventions.AuthorizeFolder("/Court_Users","Court_Users");
options.Conventions.AllowAnonymousToPage("/Shared");
);
services.AddAuthorization(options =>
options.AddPolicy("Court_Users", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim("role", "Court User")
.Build());
options.AddPolicy("NonCourt_Users", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim("role", "Non Court User")
.Build());
);
登录页面:
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, User.EmailAddress));
identity.AddClaim(new Claim(ClaimTypes.Name, User.Name.First_Name));
if (User.CourtUser)
identity.AddClaim(new Claim(ClaimTypes.Role, "Court User"));
else
identity.AddClaim(new Claim(ClaimTypes.Role, "Non Court User"));
var principal = new ClaimsPrincipal(identity);
var authProperties = new AuthenticationProperties
AllowRefresh = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(60),
IsPersistent = true
;
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(principal), authProperties);
HttpContext.Session.SetObjectAsJson("CurrentUser", User);
clearSession();
【问题讨论】:
如果您使用 IdentityServer4,则必须将您的 ApiScope 添加到策略中,然后将您的范围添加到声明中 【参考方案1】:if (User.CourtUser)
identity.AddClaim(new Claim(ClaimTypes.Role, "Court User"));
else
identity.AddClaim(new Claim(ClaimTypes.Role, "Non Court User"));
正如 Gordon Khanh Ng 所说,在登录页面中,如果您使用 ClaimTypes.Role
类型添加声明,则在启动页面中,您应该使用相同的类型来设置策略,代码如下:
public void ConfigureServices(IServiceCollection services)
services.AddRazorPages(options =>
options.Conventions.AuthorizePage("/Contact");
options.Conventions.AuthorizeFolder("/NonCourt_Users", "NonCourt_Users");
options.Conventions.AuthorizeFolder("/Court_Users", "Court_Users");
);
#region snippet1
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
#endregion
services.AddAuthorization(options =>
options.AddPolicy("Court_Users", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim(ClaimTypes.Role, "Court User")
.Build());
options.AddPolicy("NonCourt_Users", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim(ClaimTypes.Role, "Non Court User")
.Build());
);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
[注意]设置剃须刀页面约定时请注意策略名称。
那么,如果你想得到声明,你也应该使用相同的类型名称:
@page
@model CookieSample.Pages.Court_Users.CourtUserManageIndexModel
@using System.Security.Claims
@ ViewData["Title"] = "Court User Manage Index";
<h2>@ViewData["Title"]</h2>
<h2>@User.Claims.FirstOrDefault(c => c.Type == "FullName")?.Value</h2>
<h2>@User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value</h2>
结果如下:
【讨论】:
感谢您的澄清。我确实进行了更改,但这并没有为我解决问题。我仍然不明白,用户在哪里获得授权策略?他们仍然被锁定在页面之外,因为他们没有授权策略,即使他们符合它的标准? 尝试删除`HttpContext.Session.SetObjectAsJson("CurrentUser", User); clearSession();` 在登录页面中。根据您的代码,您正在将您的应用程序设置为使用 cookie 身份验证,因此,登录成功后,用户身份信息(包括用户声明)将存储在 cookie 中,然后,在下一个请求中,您可以找到用户信息来自 HttpContext.User。请检查您的 Startup.cs 文件,您是否设置了 cookie/会话过期时间?确保它没有过期。【参考方案2】:如果我理解你的情况是正确的,那么这里一定有一些误解......
在登录页面上,您使用ClaimTypes.Role
设置cookie,它代表字符串http://schemas.microsoft.com/ws/2008/06/identity/claims/role
。但在政策上,原来是RequireClaim("role", "Court User")
...我想你可能想看看。
此外,如果您使用Authorize
属性,请务必指定相应的策略。那应该就好了。
【讨论】:
我尝试将 RequireClaim("role", "Court User") 部分切换为大写的“Role”,但它没有改变任何东西。 options.Conventions.AuthorizeFolder("/Court_Users","Court_Users") 第二个参数指定需要哪个策略。您能否进一步详细说明,我不明白为什么这是不正确的。 我的意思是你应该尝试RequireClaim(ClaimTypes.Role, "Court User")
,而不仅仅是替换大写...ClaimTypes.Role
代表我上面提到的一个完整的差异字符串以上是关于用户授权 - 为用户分配授权策略 .Net Core 3.1的主要内容,如果未能解决你的问题,请参考以下文章
在 Asp.Net Core 的 Razor 页面中检查登录用户授权策略