我还看到您可以添加IProfileService以向IdentityServer4返回的令牌添加自定义声明.
一个计划是向用户添加新的声明,以授予他们访问api的不同部分的权限.但是,我无法弄清楚如何从api项目管理IdentityServer上的用户声明.我假设我应该调用IdentotyServer4来添加和删除用户声明?
此外,这是一个很好的方法,因为我不确定允许客户端为IdentityServer内部安全目的添加声明是否合理 – 并且可能导致冲突(例如,多个客户端使用’role’声明值’admin “).也许我应该在api项目中本地处理安全性,然后只使用’sub’声明来查找它们?
有没有人有这个好方法?
谢谢
解决方法
claims are about identity – not permissions
这是正确的,但身份也可能包含它是什么类型的用户(管理员,用户,经理等),可用于确定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(); } }
然后将[Authorize]属性添加到控制器以获取特定权限.这只允许特定角色访问它们,从而设置您自己的权限.
[Authorize(Roles = "CLIENT1-Admin,CLIENT2-Admin,...")] public class ValuesController : Controller { //... }
上述这些声明也可以在身份验证时传递,例如,如果您使用自定义ResourceOwnerPasswordValidator的ResourceOwner设置.您可以像验证方法一样以相同的方式传递声明.
context.Result = new GrantValidationResult( subject: user.UserId.ToString(),authenticationMethod: "custom",claims: GetClaims(user));
就像leastprivilege所说的那样,你不想使用IdentityServer来设置权限并将其作为声明传递(比如谁可以编辑什么记录),因为它们过于具体而且使令牌混乱,但是设置角色 –
grant them access to different parts of the api.
用户角色完全没问题.
希望这可以帮助.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。