C# Jwt基于令牌的身份验证无法授权

C# Jwt基于令牌的身份验证无法授权,c#,asp.net-web-api,jwt,C#,Asp.net Web Api,Jwt,我正在尝试为我的web api设置基于令牌的身份验证。到目前为止,我正在正确生成令牌,但我在授权令牌时遇到问题。通过邮递员,我在所有的帖子上都得到了401个授权。我目前已将Jwt配置如下: Startup.cs public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration;

我正在尝试为我的web api设置基于令牌的身份验证。到目前为止,我正在正确生成令牌,但我在授权令牌时遇到问题。通过邮递员,我在所有的帖子上都得到了401个授权。我目前已将Jwt配置如下:

Startup.cs

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        private IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey =
                            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                    };
                });
            
            
            services.AddMvc();
            services.AddControllers();
            services.AddSingleton<ITitleDataService, TitleDataService>();
            services.AddSingleton<IPersonDataService, PersonDataService>();
            services.AddSingleton<IUserDataService, UserDataService>();
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddControllersWithViews()
                .AddNewtonsoftJson(options =>
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                );
            services.AddMvc().AddControllersAsServices();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRequestLogging();
            
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseFileServer();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
专用IConfiguration配置{get;}
public void配置服务(IServiceCollection服务)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(选项=>
{
options.TokenValidationParameters=新的TokenValidationParameters
{
validateisuer=true,
ValidateAudience=true,
ValidateLifetime=true,
ValidateSuersigningKey=true,
IssuerSigningKey=
新的SymmetricSecurityKey(Encoding.UTF8.GetBytes(配置[“Jwt:Key”]))
};
});
services.AddMvc();
services.AddControllers();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
AddAutoMapper(AppDomain.CurrentDomain.GetAssemblys());
services.AddControllersWithViews()
.AddNewtonsoftJson(选项=>
options.SerializerSettings.ReferenceLoopHandling=Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
services.AddMvc().addControllerAsservices();
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRequestLogging();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseFileServer();
app.UseEndpoints(端点=>
{
endpoints.MapControllers();
});
}
}
}
这是我的控制器:

//LOGIN
[HttpPost("user/login/")]
public IActionResult Login(UserDto userDto)
{
    var user = _dataService.Login(userDto.Username, userDto.Password);
    IActionResult response = Unauthorized();
    if (user)
    {
        var tokenStr = GenerateJSONWebToken(userDto);
        response = Ok(new {tokenStr});
    }
    else
    {
        return BadRequest("User not authorized");
    }
    return response;
}

[Authorize]
[HttpPost("post")]
public string Post()
{
    var identity = HttpContext.User.Identity as ClaimsIdentity;
    IList<Claim> claim = identity.Claims.ToList();
    Console.WriteLine(claim.Count);
    var username = claim[0].Value;
    Console.WriteLine(username);
    return "Welcome to " + username;
}

[Authorize]
[HttpGet("GetValue")]
public ActionResult<IEnumerable<string>> Get()
{
    return new string[] {"Value1", "Value2", "Value3"};
}

private string GenerateJSONWebToken(UserDto userDto)
{
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, userDto.Username),
        new Claim(JwtRegisteredClaimNames.Email, userDto.Password),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
    };
    
    var token = new JwtSecurityToken(
        issuer: "Issuer",
        audience: "Issuer",
        claims,
        expires: DateTime.Now.AddMinutes(120),
        signingCredentials: credentials);
    
    
    var encodetoken = new JwtSecurityTokenHandler().WriteToken(token);
    return encodetoken;
}
//登录
[HttpPost(“用户/登录/”)]
公共IActionResult登录(UserDto UserDto)
{
var user=\u dataService.Login(userDto.Username,userDto.Password);
IActionResult响应=未经授权();
如果(用户)
{
var tokenStr=GenerateJSONWebToken(userDto);
response=Ok(新的{tokenStr});
}
其他的
{
返回请求(“未授权用户”);
}
返回响应;
}
[授权]
[HttpPost(“post”)]
公共字符串Post()
{
var identity=HttpContext.User.identity作为ClaimsIdentity;
IList claim=identity.Claims.ToList();
控制台写入线(索赔计数);
var username=claim[0]。值;
Console.WriteLine(用户名);
返回“欢迎使用”+用户名;
}
[授权]
[HttpGet(“GetValue”)]
公共行动结果获取()
{
返回新字符串[]{“Value1”、“Value2”、“Value3”};
}
私有字符串GenerateJSONWebToken(UserDto到UserDto)
{
var securityKey=new-SymmetricSecurityKey(Encoding.UTF8.GetBytes(_-config[“Jwt:Key”]);
var凭证=新的签名凭证(securityKey,SecurityAlgorithms.HmacSha256);
风险值索赔=新[]
{
新索赔(JwtRegisteredClaimNames.Sub,userDto.Username),
新声明(JwtRegisteredClaimNames.Email、userDto.Password),
新声明(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
};
var token=新的JwtSecurityToken(
发行人:“发行人”,
观众:“发行人”,
声称,
过期:DateTime.Now.AddMinutes(120),
签署证书:证书);
var encodetoken=new JwtSecurityTokenHandler().WriteToken(令牌);
返回编码令牌;
}
我试图重新安排中间件管道,但没有任何运气。我对代币几乎没有经验,因此我对如何解决这个问题相当迷茫。非常感谢您的建议

致以最良好的祝愿,
Jesper

这里有两个问题:您将中间件配置为验证颁发者(创建令牌的实体的URL)和访问群体(令牌用于的服务的URL),但未在配置中指定值

您的令牌是以发卡机构和访问群体作为“发卡机构”写入的,但由于您的中间件未配置为接受“发卡机构”作为发卡机构/访问群体的正确值,因此您的令牌失败


在中间件中,为颁发者和受众配置可接受的值,或者通过将
validateisuer
validateudience
设置为false来绕过颁发者和受众验证。

三个小时的调试现已结束。。。拜伦,非常感谢你!成功了!