.net core 在客户端向委托人添加自定义索赔(用于授权)
我已经能够在.net core 3.1上成功地实现我自己的IdentityServer 4身份验证服务器,并且我有一个客户端web应用程序连接到它。客户端正在成功接收访问令牌和id。令牌包含所有用户标识信息 我的下一个目标是将用户在客户机中拥有的特权添加到HttpContext.user as声明,在我获得令牌之后,在呈现任何其他页面之前。权限存储在主体ID与用户关联的数据库中 我需要在何处寻找能够添加这些声明的帮助,以便我的授权策略能够处理委托人中的声明。我希望该进程在每次发出令牌时都执行 另外,我正在使用GetClaimsFromUserInfoEndpoint=true和SaveTokens=true的Identity server代码流.net core 在客户端向委托人添加自定义索赔(用于授权),.net-core,identityserver4,asp.net-core-3.1,.net Core,Identityserver4,Asp.net Core 3.1,我已经能够在.net core 3.1上成功地实现我自己的IdentityServer 4身份验证服务器,并且我有一个客户端web应用程序连接到它。客户端正在成功接收访问令牌和id。令牌包含所有用户标识信息 我的下一个目标是将用户在客户机中拥有的特权添加到HttpContext.user as声明,在我获得令牌之后,在呈现任何其他页面之前。权限存储在主体ID与用户关联的数据库中 我需要在何处寻找能够添加这些声明的帮助,以便我的授权策略能够处理委托人中的声明。我希望该进程在每次发出令牌时都执行 另
谢谢 您可以通过使用TokenValidated事件来实现这一点
public class CustomJwtBearerEvents : JwtBearerEvents
{
public override async Task TokenValidated(TokenValidatedContext context)
{
var claims = context.Principal.Claims.ToList();
claims.Add(new Claim("key", "value"));
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Bearer")); }
}
然后在启动中注册它
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
...
options.Events = new JwtBearerEvents();
options.EventsType = typeof(CustomJwtBearerEvents);
});
您可以在identityServer4中使用Profile sevise:
services .AddIdentityServer(x =>
{
x.IssuerUri = "null";
x.Authentication.CookieLifetime = TimeSpan.FromDays(10);
})
.
.
.
.AddProfileService<ProfileService>();
services.AddIdentityServer(x=>
{
x、 IssuerUri=“null”;
x、 Authentication.CookieLifetime=TimeSpan.FromDays(10);
})
.
.
.
.AddProfileService();
这是一个很好的参考:
ProfileService可以类似于以下代码模板:
public class ProfileService : IProfileService
{
private readonly UserManager<ApplicationUser> _userManager;
public ProfileService(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var subject = context.Subject ?? throw new ArgumentNullException(nameof(context.Subject));
var subjectId = subject.Claims.Where(x => x.Type == "sub").FirstOrDefault().Value;
var user = await _userManager.FindByIdAsync(subjectId);
if (user == null)
throw new ArgumentException("Invalid subject identifier");
var claims = GetClaimsFromUser(user,subject);
context.IssuedClaims = claims.Result.ToList();
}
public async Task IsActiveAsync(IsActiveContext context)
{
var subject = context.Subject ?? throw new ArgumentNullException(nameof(context.Subject));
var subjectId = subject.Claims.Where(x => x.Type == "sub").FirstOrDefault().Value;
var user = await _userManager.FindByIdAsync(subjectId);
context.IsActive = false;
if (user != null)
{
if (_userManager.SupportsUserSecurityStamp)
{
var security_stamp = subject.Claims.Where(c => c.Type == "security_stamp").Select(c => c.Value).SingleOrDefault();
if (security_stamp != null)
{
var db_security_stamp = await _userManager.GetSecurityStampAsync(user);
if (db_security_stamp != security_stamp)
return;
}
}
context.IsActive =
!user.LockoutEnabled ||
!user.LockoutEnd.HasValue ||
user.LockoutEnd <= DateTime.Now;
}
}
private async Task<IEnumerable<Claim>> GetClaimsFromUser(ApplicationUser user,ClaimsPrincipal subject)
{
var claims = new List<Claim>
{
new Claim(JwtClaimTypes.Subject, user.Id),
new Claim(JwtClaimTypes.PreferredUserName, user.UserName),
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
};
if (!string.IsNullOrWhiteSpace(user.Name))
claims.Add(new Claim("name", user.Name));
if (!string.IsNullOrWhiteSpace(user.LastName))
claims.Add(new Claim("last_name", user.LastName));
return claims;
}
}
public类ProfileService:IProfileService
{
私有只读用户管理器_UserManager;
公共配置文件服务(UserManager UserManager)
{
_userManager=userManager;
}
公共异步任务GetProfileDataAsync(ProfileDataRequestContext上下文)
{
var subject=context.subject??抛出新ArgumentNullException(nameof(context.subject));
var subjectId=subject.Claims.Where(x=>x.Type==“sub”).FirstOrDefault()值;
var user=await\u userManager.FindByIdAsync(subjectId);
if(user==null)
抛出新ArgumentException(“无效的主题标识符”);
var索赔=GetClaimsFromUser(用户,主体);
context.IssuedClaims=claims.Result.ToList();
}
公共异步任务IsActiveAsync(IsActiveContext上下文)
{
var subject=context.subject??抛出新ArgumentNullException(nameof(context.subject));
var subjectId=subject.Claims.Where(x=>x.Type==“sub”).FirstOrDefault()值;
var user=await\u userManager.FindByIdAsync(subjectId);
context.IsActive=false;
如果(用户!=null)
{
if(_userManager.SupportsUserSecurityStamp)
{
var security_stamp=subject.Claims.Where(c=>c.Type==“security_stamp”)。选择(c=>c.Value.SingleOrDefault();
如果(安全戳!=null)
{
var db_security_stamp=wait_userManager.GetSecurityStampAsync(用户);
if(db_安全戳!=安全戳)
返回;
}
}
context.IsActive=
!user.LockoutEnabled||
!user.LockoutEnd.HasValue||
user.LockoutEnd这将是在Identity Server中,其中没有存储权限。我需要客户端上的一些东西,能够检索SubjectId并根据客户端信息向令牌添加其他声明。因此,感谢您让我走上了正确的方向。我最终使用了基于以下信息的本文关于你提供的()