在 identityserver4 中添加用户声明

Add user claims in identityserver4

我创建了 identityserver4 项目并尝试在用户登录后添加更多声明。这是我的代码

        public async Task<IActionResult> Login(LoginInputModel model)
       {
          if (ModelState.IsValid)
          {
            // validate username/password against in-memory store
                 CoreDb.Models.User user = null;
                 if (( user = await _userService.VerifyUser(model.Username, model.Password)) != null)
            {
               // var user = _users.FindByUsername(model.Username);
                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Name, user.Id.ToString(), user.Name));

                // only set explicit expiration here if user chooses "remember me". 
                // otherwise we rely upon expiration configured in cookie middleware.
                   var props = new AuthenticationProperties();
                   if (AccountOptions.AllowRememberLogin && model.RememberLogin)
              {
                            props.IsPersistent = true;
                            props.ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration);
              };

                    props.Items.Add("scheme", AccountOptions.WindowsAuthenticationSchemeName);

                    // issue authentication cookie with subject ID and username
                    await HttpContext.SignInAsync(user.Id.ToString(), user.Name, "idp", props, _userService.GetUserClaims(user).ToArray());

                    //IEnumerable<ClaimsIdentity> claimsIdentity = null;
                    //var claimsIdentity = new ClaimsIdentity(_userService.GetUserClaims(user), CookieAuthenticationDefaults.AuthenticationScheme);
                    //await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));

                    // make sure the returnUrl is still valid, and if so redirect back to authorize endpoint or a local page
                    if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))
                    {
                        return Redirect(model.ReturnUrl);
                    }

                    return Redirect("~/");
                 }

                    await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials"));

                    ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage);
          }

然而,当我在需求处理程序中调用我的 api 时,我没有看到我对用户的声明,尽管我的用户 ID 在那里。添加用户声明的合适方法是什么?

必须将声明添加到响应上下文中。如果您使用的是 aspnetidentity,那么以下方法将适用于您

确保包含 ProfileService 实现并在 ConfigureServices 连接到 IdentityServer

 .AddProfileService<ProfileService>();

 private readonly IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory;

在 GetProfileDataAsync 中,您可以包含新声明

 /// <summary>
    /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)
    /// </summary>
    /// <param name="context">The context.</param>
    /// <returns></returns>
    public override async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await userManager.FindByIdAsync(sub);
        var principal = await claimsFactory.CreateAsync(user);
        //context.AddFilteredClaims(principal.Claims);
        context.IssuedClaims.AddRange(principal.Claims);            
        context.IssuedClaims.Add(new Claim("IP Address", coreOperations.GetCurrentRequestIPAddress()));

    }

正如 Jay 已经提到的,您可以编写自己的 ProfileService。如果您不使用 aspnetidentity,您只需在登录方法中添加声明并将这些行添加到您的 ProfileService 的 GetProfileDataAsync 方法中:

 List<Claim> claims = context.Subject.Claims.Where(x => x.Type == JwtClaimTypes.Role).ToList();

  context.IssuedClaims.AddRange(claims);