.net core 使用IUserClaimsPrincipalFactory向标识添加其他声明
我试图使用IUserClaimsPrincipalFactory为身份添加一些附加声明。我创建了一个新类,该类扩展了接口IUserClaimsPrincipalFactory并重写了CreateAync。我相应地配置了服务。在我的需求处理程序中,我正在寻找那个声明,但它并不存在。这可能是一件非常愚蠢的事情,但我一直无法理解为什么它不起作用。我查看了Microsoft在“将自定义用户数据添加到标识”页面底部提供的功能,但没有任何帮助 AddPermissiontoClaim类.net core 使用IUserClaimsPrincipalFactory向标识添加其他声明,.net-core,asp.net-core-webapi,claims-based-identity,asp.net-core-3.1,.net Core,Asp.net Core Webapi,Claims Based Identity,Asp.net Core 3.1,我试图使用IUserClaimsPrincipalFactory为身份添加一些附加声明。我创建了一个新类,该类扩展了接口IUserClaimsPrincipalFactory并重写了CreateAync。我相应地配置了服务。在我的需求处理程序中,我正在寻找那个声明,但它并不存在。这可能是一件非常愚蠢的事情,但我一直无法理解为什么它不起作用。我查看了Microsoft在“将自定义用户数据添加到标识”页面底部提供的功能,但没有任何帮助 AddPermissiontoClaim类 public cla
public class AddPermissiontoClaim : UserClaimsPrincipalFactory<ApiUser, IdentityRole>
{
public AddPermissiontoClaim(
UserManager<ApiUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(ApiUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>()
{
new Claim("Permissions", "Read")
};
identity.AddClaims(claims);
return principal;
}
}
公共类AddPermissiontoClaim:UserClaimsPrincipalFactory
{
公共添加许可证索赔(
用户管理器用户管理器,
RoleManager RoleManager,
IOOptions Accessor):基本(用户管理器、角色管理器、Options Accessor)
{
}
公共异步覆盖任务CreateAync(ApiUser用户)
{
var principal=await base.CreateAsync(用户);
var identity=(ClaimsIdentity)principal.identity;
var索赔=新列表()
{
新声明(“权限”、“读取”)
};
身份。添加索赔(索赔);
返还本金;
}
}
在启动类中注册类。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<ApiUserIdentityDbContext>(opt =>{
opt.UseSqlServer(Configuration.GetConnectionString("DefaultConStr"));
});
services.AddAutoMapper(typeof(MappingProfiles));
services.AddScoped<ICustomer,CustomerRepository>();
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.Configure<ApiBehaviorOptions>(opt => {
opt.InvalidModelStateResponseFactory = context => {
var errors = context.ModelState
.Where(v => v.Value.Errors.Count() > 0)
.SelectMany(x => x.Value.Errors)
.Select(v => v.ErrorMessage);
var error = new ApiValidationError {
Errors = errors
};
return new BadRequestObjectResult(error);
};
});
services.AddDefaultIdentity<ApiUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApiUserIdentityDbContext>();
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opt => {
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Token:Key"])),
ValidateAudience = true,
ValidateIssuer = true,
ValidAudience = Configuration["Token:Audience"],
ValidIssuer = Configuration["Token:Issuer"]
};
});
services.AddScoped<ITokenService, TokenService>();
services.AddScoped<IUserClaimsPrincipalFactory<ApiUser>, AddPermissiontoClaim>();
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
}
public void配置服务(IServiceCollection服务)
{
services.AddControllers();
services.AddDbContext(opt=>{
opt.UseSqlServer(Configuration.GetConnectionString(“DefaultConStr”);
});
AddAutoMapper(类型(映射配置文件));
services.addScope();
服务.addScope(typeof(IGenericRepository)、typeof(genericpository));
services.addScope();
services.Configure(opt=>{
opt.InvalidModelStateResponseFactory=上下文=>{
var errors=context.ModelState
.Where(v=>v.Value.Errors.Count()>0)
.SelectMany(x=>x.Value.Errors)
.选择(v=>v.ErrorMessage);
var error=新的ApiValidationError{
错误=错误
};
返回新的BadRequestObjectResult(错误);
};
});
services.AddDefaultIdentity()
.AddRoles()
.AddEntityFrameworkStores();
services.AddAuthentication(x=>
{
x、 DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme;
x、 DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opt=>{
opt.TokenValidationParameters=新的TokenValidationParameters
{
ValidateSuersigningKey=true,
IssuerSigningKey=new-SymmetricSecurityKey(Encoding.UTF8.GetBytes(配置[“令牌:密钥])),
ValidateAudience=true,
validateisuer=true,
Validudience=配置[“令牌:受众”],
ValidisUser=配置[“令牌:颁发者”]
};
});
services.addScope();
services.addScope();
services.AddSingleton();
}
需求处理程序
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var permissionsClaim = context.User.Claims.SingleOrDefault(c => c.Type == "Permissions");
if (permissionsClaim == null)
return Task.CompletedTask;
//TODO
if (permissionsClaim.Value.ThisPermissionAllowed(requirement.Name))
context.Succeed(requirement);
return Task.CompletedTask;
}
}
公共类PermissionHandler:AuthorizationHandler
{
受保护的覆盖任务HandleRequirementAsync(授权HandlerContext上下文,许可要求)
{
var permissionsClaim=context.User.Claims.SingleOrDefault(c=>c.Type==“Permissions”);
if(permissionsClaim==null)
返回Task.CompletedTask;
//待办事项
if(permissionsLaim.Value.ThisPermissionAllowed(requirement.Name))
成功(要求);
返回Task.CompletedTask;
}
}
更新:
目标是完成与下面的中间件类似的工作。除了需要访问数据库并获取要添加到声明中的权限列表之外,它与中间件配合良好
public class AddClaimsMiddleware
{
private readonly RequestDelegate _next;
public AddClaimsMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
if(httpContext.User.Identity.IsAuthenticated)
{
var claims = new List<Claim>
{
new Claim(PermissionConstant.PackedPermissionType, "Admin")
};
var appIdentity = new ClaimsIdentity(claims);
httpContext.User.AddIdentity(appIdentity);
await _next(httpContext);
}
}
}
public类addclaimsmiddle软件
{
private readonly RequestDelegate\u next;
公共AddClaimsMiddleware(RequestDelegate下一步)
{
_下一个=下一个;
}
公共异步任务InvokeAsync(HttpContext HttpContext)
{
if(httpContext.User.Identity.IsAuthenticated)
{
var索赔=新列表
{
新声明(PermissionConstant.PackedPermissionType,“Admin”)
};
var appIdentity=新的索赔实体(索赔);
httpContext.User.AddIdentity(appIdentity);
等待下一步(httpContext);
}
}
}
您应该将AddPermissiontoClaim
的ClaimTypes
与需求处理程序中的类型保持一致。检查更多详细信息。@MichaelWang我做了更改。索赔仍然不存在。我在需求中放置了一个断点,并检查其中有哪些声明。它没有权限声明。您似乎从未添加权限声明。跟随检查。@MichaelWang感谢您的帮助。我看到了这些台阶。事实上,我将示例代码复制到项目中,得到了相同的结果。我不得不将ApplicationUser更改为ApiUser,因为它继承自IdentityUser。当我检查索赔时,它有8澳元,iss,nbf,exp,iat,电子邮件地址,出生日期,givenname。管理员不是其中之一。我将创建一个全新的项目,这样我就可以处理这个问题。你应该让你的AddPermissiontoClaim的ClaimTypes
与需求处理程序中的类型保持一致。检查更多详细信息。@MichaelWang我做了更改。索赔仍然不存在。我在需求中放置了一个断点,并检查其中有哪些声明。它没有权限声明。您似乎从未添加权限声明。跟随检查。@MichaelWang感谢您的帮助。我看到了这些台阶。事实上,我将示例代码复制到项目中,得到了相同的结果。我不得不去看电影