在identityserver4中添加用户声明
我已经创建了identityserver4项目,并尝试在用户登录后添加更多声明。这是我的密码在identityserver4中添加用户声明,identityserver4,Identityserver4,我已经创建了identityserver4项目,并尝试在用户登录后添加更多声明。这是我的密码 public async Task<IActionResult> Login(LoginInputModel model) { if (ModelState.IsValid) { // validate username/password against in-memory store
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);
}
公共异步任务登录(LoginInputModel)
{
if(ModelState.IsValid)
{
//根据内存存储验证用户名/密码
CoreDb.Models.User=null;
if((user=wait _userService.VerifyUser(model.Username,model.Password))!=null)
{
//var user=\u users.FindByUsername(model.Username);
wait_events.RaiseAsync(新的userloginsAccessEvent(user.Name,user.Id.ToString(),user.Name));
//仅当用户选择“记住我”时才在此处设置显式过期。
//否则,我们依赖于cookie中间件中配置的过期。
var props=新的AuthenticationProperties();
if(AccountOptions.AllowRememberLogin&&model.RememberLogin)
{
props.ispersist=true;
props.ExpiresUtc=DateTimeOffset.UtcNow.Add(AccountOptions.rememberLoginDuration);
};
添加(“方案”,AccountOptions.WindowsAuthenticationSchemeName);
//发出具有主题ID和用户名的身份验证cookie
等待HttpContext.SignInAsync(user.Id.ToString(),user.Name,“idp”,props,_userService.GetUserClaims(user.ToArray());
//IEnumerable claimsIdentity=null;
//var claimsIdentity=new claimsIdentity(_userService.GetUserClaims(user),CookieAuthenticationDefaults.AuthenticationScheme);
//等待HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,新的ClaimsPrincipal(ClaimsEntity));
//确保returnUrl仍然有效,如果有效,则重定向回授权端点或本地页面
if(_interaction.IsValidReturnUrl(model.ReturnUrl)| | Url.IsLocalUrl(model.ReturnUrl))
{
返回重定向(model.ReturnUrl);
}
返回重定向(“~/”);
}
wait_events.RaiseAsync(新用户登录失败事件(model.Username,“无效凭据”);
ModelState.AddModelError(“,AccountOptions.InvalidCredentialsErrorMessage”);
}
但是,尽管我的用户id在需求处理程序中调用api,但我没有看到我对用户的声明。添加用户声明的适当方法是什么?必须将声明添加到响应上下文中。如果您使用的是aspnetidentity,则以下方法适用于您 确保在ConfigureServices中包括ProfileService实现并连接到IdentityServer
.AddProfileService<ProfileService>();
.AddProfileService();
私有只读IUserClaimsPrincipalFactory 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()));
}
//
///每当请求有关用户的声明时(例如,在令牌创建期间或通过userinfo端点),都会调用此方法
///
///上下文。
///
公共重写异步任务GetProfileDataAsync(ProfileDataRequestContext上下文)
{
var sub=context.Subject.GetSubjectId();
var user=await userManager.FindByIdAsync(sub);
var principal=await claimsFactory.CreateAsync(用户);
//context.AddFilteredClaims(委托人索赔);
context.IssuedClaims.AddRange(委托人索赔);
添加(新声明(“IP地址”,coreOperations.GetCurrentRequestIPAddress());
}
必须将声明添加到响应上下文中。如果您使用的是AsNetIdentity,则以下方法适用于您
确保在ConfigureServices中包括ProfileService实现并连接到IdentityServer
.AddProfileService<ProfileService>();
.AddProfileService();
私有只读IUserClaimsPrincipalFactory 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()));
}
//
///每当请求有关用户的声明时(例如,在令牌创建期间或通过userinfo端点),都会调用此方法
///
///上下文。
///
公共重写异步任务GetProfileDataAsync(ProfileDataRequestContext上下文)
{
var sub=context.Subject.GetSubjectId();
var user=await userManager.FindByIdAsync(sub);
var principal=await claimsFactory.CreateAsync(用户);
//context.AddFilteredClaims(委托人索赔);
context.IssuedClaims.AddRange(委托人索赔);
添加(新声明(“IP地址”,coreOperations.GetCurrentRequestIPAddress());
}
正如Jay已经提到的,您可以编写自己的ProfileService。如果您不使用AsNetIdentity,您可以在Login方法中添加声明,并将以下行添加到ProfileService的GetProfileDataAsync方法中:
List<Claim> claims = context.Subject.Claims.Where(x => x.Type == JwtClaimTypes.Role).ToList();
context.IssuedClaims.AddRange(claims);
List claims=context.Subject.claims.Where(x=>x.Type==JwtClaimTypes.Role).ToList();
context.IssuedClaims.AddRange(索赔);
正如Jay已经提到的,您可以编写自己的ProfileService。如果您不使用AsNetIdentity,您可以在Login方法中添加声明,并将以下行添加到ProfileService的GetProfileDataAsync方法中:
List<Claim> claims = context.Subject.Claims.Where(x => x.Type == JwtClaimTypes.Role).ToList();
context.IssuedClaims.AddRange(claims);
List claims=context.Subject.claims.Where(x=>x.Type==JwtClaimTypes.Role).ToList();
context.IssuedClaims.AddRange(索赔);
我发现了问题。我需要在ApiResource定义中添加UserClaim类型。否则,IdentityServer 4将筛选我在HttpContext.SignInAsync中添加的任何声明。您建议的方法可能类似于在登录期间添加用户声明。我会在有时间时尝试此方法。我尝试了ProfileService。它似乎适用于ResourceOwnerPasswordAndClientCredentials gr