加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-web-api – 如何在IdentityServer4中在运行时添加/管理

发布时间:2020-12-16 03:17:40 所属栏目:asp.Net 来源:网络整理
导读:我想在一个新项目中使用IdentityServer4.我在PluralSight视频“了解ASP.NET核心安全性”中看到,IdentityServer4可以与基于声明的安全性一起使用,以保护Web API.我已将IdentityServer4设置为单独的项目/解决方案. 我还看到您可以添加IProfileService以向Ident
我想在一个新项目中使用IdentityServer4.我在PluralSight视频“了解ASP.NET核心安全性”中看到,IdentityServer4可以与基于声明的安全性一起使用,以保护Web API.我已将IdentityServer4设置为单独的项目/解决方案.

我还看到您可以添加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.

用户角色完全没问题.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读