- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我从 ASP.NET Identity 的声明授权开始,如果我的应用程序中需要“角色”概念,我想阐明处理它们的方式。
注意:我对这个真的很陌生,所以所有的概念都在我脑海中飞舞,请多多关照,对于任何概念的进一步澄清/更正将不胜感激。
1.- 假设,我需要 Admin 和 User 角色的“角色”概念,所以我的第一个想法是向 ApplicationUser
添加声明,例如:
user.Claims.Add(new IdentityUserClaim { ClaimType = "Role", ClaimValue = "Admin" });
*“用户”是 ApplicationUser
。
但后来我读到它已经由框架完成,因为它有一些预定义的声明类型,所以上面的代码可以是:
user.Claims.Add(new IdentityUserClaim { ClaimType = ClaimTypes.Role, ClaimValue = "Admin" });
这种方法正确吗?或者我应该使用“旧”角色概念并向用户添加角色,例如:
await _roleManager.CreateAsync(new IdentityRole("Admin"));
await _userManager.AddToRoleAsync(user, "Admin");
2.- 现在假设我将角色定义为声明,我如何检查它们的授权?我的意思是,它会起作用吗?
[Authorize(Roles = "Admin")]
或者我应该包含一个政策声明来检查角色声明吗?
/* In startup ConfigureServices method*/
options.AddPolicy("IsAdmin", policy => {
policy.RequireClaim(ClaimTypes.Role, "Admin");
});
...
/*In a controller class*/
[Authorize(Policy = "IsAdmin")]
3.- 现在,存储自定义声明的正确方法是什么?我的意思是,ASP.NET 的 ClaimTypes
类只是一堆 const string
值,所有关于 Claims 的示例代码都将它们存储在类似的类中,例如:
public static class ClaimData
{
public static List AdminClaims { get; set; } = new List
{
"Add User",
"Edit User",
"Delete User"
};
}
可以吗?
最后说明。- 我还在互联网上看到了“角色声明”的概念,这篇博文对此进行了解释:http://benfoster.io/blog/asp-net-identity-role-claims
那是什么?如果我还不够困惑,现在还有第三种授权用户的方式。使用角色作为声明是否更好?
câu trả lời hay nhất
您描述的方法似乎是正确的。一切都取决于您的要求。
假设您的应用程序中有多个功能,如果您选择使用角色,则属于该功能的代码必须每次检查用户是否在一组特定的角色中才能使用该功能。当功能和角色增长时,这种方法变得非常难以管理,因为您必须考虑将角色组合到每个功能中。在此示例中,只有 PowerUser
hoặc Administrator
用户才能执行管理操作 X
。现在,这看起来简单明了,但是,如果您添加一个新角色 ALittleBitMorePowerful
会发生什么,这是一个 Người sử dụng
也可以执行 X
操作。要获得此结果,您必须检查所有内容并更改检查(这意味着重新测试整个内容)。
如果您设计的功能X
带有声明CanPerformX
,您将引入一个抽象层:您的代码将不关心用户的角色,但会检查只为自己的主张。如果您曾经修改声明与用户的关联方式,您的有效代码将不会改变(这最终意味着没有引入正式的回归)。
角色被设计为广泛的,而声明被设计为细粒度的。但是,当您在链接中阅读时,您可能会认为一个角色是“大角色”,或者一个角色是“小角色”。
我发布了一小段我的代码,它支持自定义角色但固定声明。定义声明
internal static class PolicyClaims
{
public const string AdministratorClaim = @"http://myorganization/2019/administrator";
public const string Operation1Claim = @"http://myorganization/2019/op1";
public const string Operation2Claim = @"http://myorganization/2019/op2";
public const string ObtainedClaim = @"true";
}
定义策略
internal static class Policies
{
public const string RequireAdministrator = "RequireAdministrator";
public const string RequireOp1 = "RequireOp1";
public const string RequireOp2 = "RequireOp2";
public const string AlwaysDeny = "AlwaysDeny";
public static void ConfigurePolicies(IServiceCollection services)
{
services.AddAuthorization(options => options.AddPolicy(RequireAdministrator, policy => policy.RequireClaim(PolicyClaims.AdministratorClaim)));
services.AddAuthorization(options => options.AddPolicy(RequireOp1, policy => policy.RequireClaim(PolicyClaims.Operation1Claim)));
services.AddAuthorization(options => options.AddPolicy(RequireOp2, policy => policy.RequireClaim(PolicyClaims.Operation2Claim)));
services.AddAuthorization(options => options.AddPolicy(AlwaysDeny, policy => policy.RequireUserName("THIS$USER\n\r\t\0cannot be created")));
}
}
hiện hữu Startup.RegisterServices
中注册策略
Policies.ConfigurePolicies(services);
在对用户进行身份验证的地方,根据您的逻辑决定需要添加哪些声明(省略了一些部分以关注概念)
[AllowAnonymous]
[Route("api/authentication/authenticate")]
[HttpPost()]
public async Task Authenticate([FromBody] LoginModel model)
{
if (ModelState.IsValid)
{
var user = m_UserManager.Users.FirstOrDefault(x => x.UserName == model.UserName);
if (user == null)
{
...
}
khác
{
var result = await m_SignInManager.CheckPasswordSignInAsync(user, model.Password, false);
if (result.Succeeded)
{
var handler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.Name, model.UserName)
}),
Expires = DateTime.UtcNow.AddHours(2),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(InstanceSettings.JWTKey), SecurityAlgorithms.HmacSha256Signature)
};
var roles = await m_UserManager.GetRolesAsync(user);
AddClaims(tokenDescriptor, roles);
var token = handler.CreateToken(tokenDescriptor);
var tokenString = handler.WriteToken(token);
return ...
}
khác
{
...
}
}
}
return ...
}
private static void AddClaims(SecurityTokenDescriptor tokenDescriptor, IList roles)
{
if (roles.Any(x => string.Equals(Constants.AdministratorRoleName, x, StringComparison.OrdinalIgnoreCase)))
{
tokenDescriptor.Subject.AddClaim(new Claim(PolicyClaims.AdministratorClaim, PolicyClaims.ObtainedClaim));
tokenDescriptor.Subject.AddClaim(new Claim(PolicyClaims.Operation1Claim, PolicyClaims.ObtainedClaim));
tokenDescriptor.Subject.AddClaim(new Claim(PolicyClaims.Operation2Claim, PolicyClaims.ObtainedClaim));
}
... query the database and add each claim with value PolicyClaims.ObtainedClaim ...
}
最后,您可以使用策略来保护您的代码:
[Authorize(Policy = Policies.RequireAdministrator)]
[HttpPost("execute")]
public async Task ExecuteOperation([FromBody] CommandModel model)
{
...
}
请注意,在这种方法中,我将某些声明硬编码给管理员,因为我想阻止管理员删除某些声明。但是,这不是强制性的。
关于c# - Clarifying Identity Authorization : using Claims as Roles, Roles and Claims or 角色声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45997100/
如果达到我的自定义政策中的特定步骤/条件,我将尝试从 claim 包中删除所有 claim ,但我找不到任何相关信息。然后我尝试对字符串使用 NullClaim Transformation,但我找不
我正在实现一个 oAuth 服务器并且需要存储刷新 token ,为此我(目前)选择将 token 序列化为 JSON。 虽然我可以看到 JSON 包含重新水化所需的一切,但当我使用 token.Fr
我正在创建一个简单的 WebApi,它允许用户连接到 Facebook。当我从 facebook 取回 accessToken 时,我调用 RegisterExternal 来创建一个 Asp.Net
我似乎无法序列化 Claim - 我做错了什么?使用此方法的其他对象序列化工作正常。 代码 var client = new MongoClient("mongodb://localhost:2701
我正在尝试在 ASP.NET Core 中使用基于 Windows 身份验证的声明授权。我有一个设置用户声明的声明转换器。我还通过 DbContext 将 IPrincipal 注入(inject)到
我直接使用 AspNetUserClaims 表,因为它主要属于我的 ASP.NET 应用程序,但也被 Windows 应用程序使用。 ASP.NET 应用程序使用 Google 进行外部登录,而 W
我从 ASP.NET Identity 的声明授权开始,如果我的应用程序中需要“角色”概念,我想阐明处理它们的方式。 注意:我对这个真的很陌生,所以所有的概念都在我脑海中飞舞,请多多关照,对于任何概念
我已经安装了 WSO2 IS 5.2.0,但我无法检索自定义创建的声明。 我为方言添加了新声明 http://wso2.org/claims我还添加了将相同属性映射到方言的新声明 http://wso
我们正在尝试使用组织 AD 作为 IDP,使用 SAML 和 Azure B2C 作为服务提供商 (SP) 设置 SSO。Org AD 被许多其他 SP 供应商用作 IDP(SAML),并且工作得很好
我正在开发一个 MVC4 应用程序,该应用程序使用 ADFS 对公司域用户进行身份验证,我已经编写了代码,但收到如下错误,我是否没有收到 claim ? System.InvalidCastExcep
我收到针对 Azure AD 进行身份验证的用户的组超额 claim 。如下所示: {"src1":{"endpoint":"https://graph.windows.net/TENANTID/us
我收到针对 Azure AD 进行身份验证的用户的组超额 claim 。如下所示: {"src1":{"endpoint":"https://graph.windows.net/TENANTID/us
是否可以将 SAML 声明发送到 ADFS,然后让 ADFS 使用来自传入声明的值来生成自己的声明? 基本上,我们需要发送 a)关于用户的信息(相当简单),以及 b)关于目标的信息(手头的问题)。目标
我目前正在开发 API。 token 从 IdentityServer4 返回。 我正在尝试从 token 声明中取回子 ID,即当前授权用户的 ID。我可以在此处的声明中看到它。 { "nbf"
我目前正在使用 asp.net core 设计一个系统,我想实现基于声明的授权,但有一个特定的部分让我感到困惑。 当提出声明时,声明将包括类型和值以及可选的发行者。在处理程序中,可以在确认访问之前检查
我需要从 JWT 中提取声明。 看来这应该是理所当然的。 它已签名,从我得到的标题中: { "alg": "RS256", "typ": "JWT" } 智威汤逊: eyJhbGciOiJSU
我是一个长期的 .NET Framework/WebForms 开发人员,并且正在为一个新项目转向 Core (2.1)。我已经建立了基础部分,一个 VS 解决方案包含一个 DAL 项目和一个 Web
我正在尝试根据特定声明的值过滤用户。 我使用 ASP .Net Core 3 和 RavenDB。 filteredData = data.Search(d => d.Email, model.sea
我将 WSO2 身份服务器用于单点登录实现。 在我的演示应用程序中,我试图从我自己的 JDBC 数据库中获取经过身份验证的用户的自定义声明属性。 我关注了这个 blog普什帕兰卡。 这适用于 Iden
我想通过Identity内的Claim访问我的电子邮件地址 我尝试访问为: var email = User.Identity.GetClaimsByType("emailaddress").ToSt
Tôi là một lập trình viên xuất sắc, rất giỏi!