C# 扩展基于角色的授权时面临的问题

C# 扩展基于角色的授权时面临的问题,c#,asp.net-mvc,asp.net-core,model-view-controller,C#,Asp.net Mvc,Asp.net Core,Model View Controller,当我试图使用Microsoft identity扩展基于角色的授权时,我遇到了一些问题 调用登录操作方法时,若未将角色添加到索赔列表中,它将生成令牌 var claims = new List<Claim> { new Claim(ClaimTypes.Name,user.UserName), new Claim(ClaimTypes.NameIdentifier,user.Id.ToString())

当我试图使用Microsoft identity扩展基于角色的授权时,我遇到了一些问题

调用登录操作方法时,若未将角色添加到索赔列表中,它将生成令牌

 var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name,user.UserName),
            new Claim(ClaimTypes.NameIdentifier,user.Id.ToString())
        };

        var roles = await _userManager.GetRolesAsync(user);  // If remove this await call then it work fine.

        foreach (var role in roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }
var索赔=新列表
{
新索赔(索赔类型.名称,用户.用户名),
新声明(ClaimTypes.NameIdentifier,user.Id.ToString())
};
var roles=await_userManager.GetRolesAsync(用户);//如果删除此等待呼叫,则其工作正常。
foreach(角色中的var角色)
{
添加(新索赔(ClaimTypes.Role,Role));
}
在向声明中添加新角色并生成令牌之后,我确实在几分钟内收到了来自服务器的任何响应,一段时间后,它将显示如下所示的错误

错误是:调用的目标已引发异常

在ConfigureServices方法下的Startup.cs类中

    services.AddDbContext<DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            IdentityBuilder builder = services.AddIdentityCore<User>(opt =>
            {
                opt.Password.RequireDigit = false;
                opt.Password.RequiredLength = 4;
                opt.Password.RequireNonAlphanumeric = false;
                opt.Password.RequireUppercase = false;
            });

            builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
            builder.AddEntityFrameworkStores<DataContext>();
            builder.AddRoleValidator<RoleValidator<Role>>();
            builder.AddRoleManager<RoleManager<Role>>();
            builder.AddSignInManager<SignInManager<User>>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(auth =>
            {
                auth.TokenValidationParameters = new TokenValidationParameters()
                {
                    // ValidateIssuer = true,
                    // ValidIssuer = Configuration["AuthSettings:Issuer"],
                    // ValidateAudience = true,
                    // ValidAudience = Configuration["AuthSettings:Audience"],
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["AuthSettings:Key"])),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

   services.AddControllers(opt =>
            {
                var policy = new AuthorizationPolicyBuilder()
           .RequireAuthenticatedUser()
           .Build();
                opt.Filters.Add(new AuthorizeFilter(policy));
            })
             .AddNewtonsoftJson(options =>
              options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddDbContext(x=>x.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”));
IdentityBuilder builder=services.AddIdentityCore(opt=>
{
opt.Password.RequireDigit=false;
opt.Password.RequiredLength=4;
opt.Password.RequireNonAlphanumeric=false;
opt.Password.RequireUppercase=false;
});
builder=newidentitybuilder(builder.UserType、typeof(Role)、builder.Services);
builder.AddEntityFrameworkStores();
builder.AddRoleValidator();
builder.AddRoleManager();
builder.AddSignInManager();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(auth=>
{
auth.TokenValidationParameters=新的TokenValidationParameters()
{
//validateisuer=true,
//ValidisUser=配置[“AuthSettings:Issuer”],
//ValidateAudience=true,
//Validudience=配置[“AuthSettings:访问群体”],
ValidateSuersigningKey=true,
IssuerSigningKey=new-SymmetricSecurityKey(Encoding.ASCII.GetBytes(配置[“AuthSettings:Key”]),
validateisuer=false,
ValidateAudience=false
};
});
services.AddControllers(opt=>
{
var policy=new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()文件
.Build();
添加(新的授权过滤器(策略));
})
.AddNewtonsoftJson(选项=>
options.SerializerSettings.ReferenceLoopHandling=Newtonsoft.Json.ReferenceLoopHandling.Ignore);
在AuthController中

 [HttpPost("login")]
    public async Task<IActionResult> Login(UserForLoginDto loginDto)
    {

        var user = await _userManager.FindByNameAsync(loginDto.Username);
        var result = await _signInManager.CheckPasswordSignInAsync(user, loginDto.Password, false);
        if (result.Succeeded)
        {
            var appUsers = await _userManager.Users.Include(e => e.Photos)
            .FirstOrDefaultAsync(next => next.NormalizedUserName == loginDto.Username.ToUpper());

            var userToReturn = _mapper.Map<UserForListDto>(appUsers);
            return Ok(new
            {
                token = GeneratejwtToken(appUsers),
                user = userToReturn

            });
        }
        else
        {
            return Unauthorized();
        }



    }

    private async Task<string> GeneratejwtToken(User user)
    {
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name,user.UserName),
            new Claim(ClaimTypes.NameIdentifier,user.Id.ToString())
        };

        var roles = await _userManager.GetRolesAsync(user);

        foreach (var role in roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["AuthSettings:Key"]));
        var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = signingCredentials

        };
        var TokenHandler = new JwtSecurityTokenHandler();
        var token = TokenHandler.CreateToken(tokenDescriptor);
        return TokenHandler.WriteToken(token);
    }
[HttpPost(“登录”)]
公共异步任务登录(UserForLoginTo LoginTo)
{
var user=await\u userManager.FindByNameAsync(loginDto.Username);
var result=wait _signInManager.CheckPasswordSignInAsync(user,loginDto.Password,false);
if(result.successed)
{
var appUsers=await\u userManager.Users.Include(e=>e.Photos)
.FirstOrDefaultAsync(next=>next.NormalizedUserName==loginDto.Username.ToUpper());
var userToReturn=_mapper.Map(appUsers);
返回Ok(新的
{
token=GeneratejwtToken(appUsers),
用户=用户返回
});
}
其他的
{
未经授权返回();
}
}
专用异步任务GeneratejwtToken(用户)
{
var索赔=新列表
{
新索赔(索赔类型.名称,用户.用户名),
新声明(ClaimTypes.NameIdentifier,user.Id.ToString())
};
var roles=await\u userManager.GetRolesAsync(用户);
foreach(角色中的var角色)
{
添加(新索赔(ClaimTypes.Role,Role));
}
var key=new-SymmetricSecurityKey(Encoding.UTF8.GetBytes(_-config[“AuthSettings:key]”));
var signingCredentials=新的signingCredentials(key,SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor=新的SecurityTokenDescriptor
{
主题=新的索赔实体(索赔),
Expires=DateTime.Now.AddDays(1),
SigningCredentials=签名凭据
};
var TokenHandler=new JwtSecurityTokenHandler();
var token=TokenHandler.CreateToken(tokenDescriptor);
返回TokenHandler.WriteToken(令牌);
}
我解决了这个问题, 调用GeneratejwtToken方法时,我忘记了使用wait关键字,因为该方法是异步方法

token = await GeneratejwtToken(appUsers)
我解决了这个问题, 调用GeneratejwtToken方法时,我忘记了使用wait关键字,因为该方法是异步方法

token = await GeneratejwtToken(appUsers)