Lev*_*bot 5 authorization claims asp.net-web-api asp.net-core identityserver4
我想在一个新项目中使用IdentityServer4.我在PluralSight视频"了解ASP.NET核心安全性"中看到,IdentityServer4可以与基于声明的安全性一起使用,以保护Web API.我已将IdentityServer4设置为单独的项目/解决方案.
我还看到您可以添加IProfileService以向IdentityServer4返回的令牌添加自定义声明.
一个计划是向用户添加新的声明,以授予他们访问api的不同部分的权限.但是,我无法弄清楚如何从api项目管理IdentityServer上的用户声明.我假设我应该调用IdentotyServer4来添加和删除用户声明?
此外,这是一个很好的方法,因为我不确定允许客户端为IdentityServer内部安全目的添加声明是否合理 - 并且可能导致冲突(例如,多个客户端使用'role'声明值'admin ").也许我应该在api项目中本地处理安全性,然后只使用'sub'声明来查找它们?
有没有人有这个好方法?
谢谢
老问题,但仍然相关。正如最低权限在评论中所说
声明是关于身份 - 而不是权限
这听起来是对的,但身份也可以包含它是什么类型的用户(管理员、用户、经理等),可用于确定您的 API 中的权限。也许设置具有特定权限的用户角色?本质上,如果 CLIENT1-Admin 不应与 CLIENT2-Admin 具有相同的权限,您也可以在客户端之间拆分角色以进行更多控制。
因此,将您的角色作为IProfileService.
public class ProfileService : IProfileService
{
private readonly Services.IUserService _userService;
public ProfileService(Services.IUserService userService)
{
_userService = userService;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
try
{
switch (context.Client.ClientId)
{
//setup profile data for each different client
case "CLIENT1":
{
//sub is your userId.
var userId = context.Subject.Claims.FirstOrDefault(x => x.Type == "sub");
if (!string.IsNullOrEmpty(userId?.Value) && long.Parse(userId.Value) > 0)
{
//get the actual user object from the database
var user = await _userService.GetUserAsync(long.Parse(userId.Value));
// issue the claims for the user
if (user != null)
{
var claims = GetCLIENT1Claims(user);
//add the claims
context.IssuedClaims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
}
}
}
break;
case "CLIENT2":
{
//...
}
}
}
catch (Exception ex)
{
//log your exceptions
}
}
// Gets all significant user claims that should be included
private static Claim[] GetCLIENT1Claims(User user)
{
var claims = new List<Claim>
{
new Claim("user_id", user.UserId.ToString() ?? ""),
new Claim(JwtClaimTypes.Name, user.Name),
new Claim(JwtClaimTypes.Email, user.Email ?? ""),
new Claim("some_other_claim", user.Some_Other_Info ?? "")
};
//----- THIS IS WHERE ROLES ARE ADDED ------
//user roles which are just string[] = { "CLIENT1-Admin", "CLIENT1-User", .. }
foreach (string role in user.Roles)
claims.Add(new Claim(JwtClaimTypes.Role, role));
return claims.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
然后[Authorize]为您的控制器添加属性以获得您的特定权限。这仅允许特定角色访问它们,因此设置您自己的权限。
[Authorize(Roles = "CLIENT1-Admin, CLIENT2-Admin, ...")]
public class ValuesController : Controller
{
//...
}
Run Code Online (Sandbox Code Playgroud)
例如,如果您使用带有 custom 的 ResourceOwner 设置,则上述这些声明也可以通过身份验证传递ResourceOwnerPasswordValidator。您可以像这样在 Validation 方法中以相同的方式传递声明。
context.Result = new GrantValidationResult(
subject: user.UserId.ToString(),
authenticationMethod: "custom",
claims: GetClaims(user));
Run Code Online (Sandbox Code Playgroud)
所以就像leastprivilege所说的那样,您不想使用IdentityServer来设置权限并将其作为声明传递(例如谁可以编辑什么记录),因为它们太具体并且使令牌混乱,但是设置角色-
授予他们访问 api 不同部分的权限。
这对于用户角色来说完全没问题。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
1015 次 |
| 最近记录: |