如何在.net Core 2.2中实现JWT令牌

Cra*_*aig 3 c# jwt

我已经为此奋斗了几个小时,似乎无法追踪为什么我对[Authorize]启用的端点的所有呼叫均因401而失败。

在我的.Net Core 2.2 Web API项目中,在Startup.cs中,我设置了身份验证:

public void ConfigureServices(IServiceCollection services)
        {
            var jwtSettings = new JwtSettings();
            Configuration.Bind(nameof(jwtSettings), jwtSettings);
            services.AddSingleton(jwtSettings);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            // Add the JWT Bearer token configuration
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("craigcraigcraigcraigcraigcraig")),//jwtSettings.Secret)),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    RequireExpirationTime = false,
                    ValidateLifetime = true
                };
            });

            services.AddSwaggerGen(x =>
            {
                x.SwaggerDoc("v1", new Info { Title = "My Backend", Version = "v1" });
                var security = new Dictionary<string, IEnumerable<string>>
                {
                    {"Bearer", new string[0]}
                };
                x.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "JWT Authorisation header using the bearer scheme",
                    Name = "Authorisation",
                    In = "header",
                    Type = "apiKey"
                });
                x.AddSecurityRequirement(security);

            });
        }
Run Code Online (Sandbox Code Playgroud)
  • 注意,我对我的密钥进行了硬编码,因为我不确定这是否是问题所在。

然后,在配置中,我要告诉我的应用程序UseAuthentication并确保Swagger知道我需要一些授权帮助。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseAuthentication();

            // This is getting the seetings from a 'SwaggerOptions' section within appSettings.[Env].json, and bind that data to the SwaggerOptions class.
            var swaggerOptions = new Options.SwaggerOptions();
            Configuration.GetSection(nameof(Options.SwaggerOptions)).Bind(swaggerOptions);

            app.UseSwagger(option => { option.RouteTemplate = swaggerOptions.JsonRoute; });
            app.UseSwaggerUI(option => { option.SwaggerEndpoint(swaggerOptions.UiEndpoint, swaggerOptions.Description); });


            app.UseMvc();
        }
Run Code Online (Sandbox Code Playgroud)

我有一个接收用户名和密码的端点。我进行了一些检查,如果用户名和密码正确,则会生成一个令牌:

private string GenerateToken(UserDto user)
        {
            var key = Encoding.ASCII.GetBytes("craigcraigcraigcraigcraigcraig");// config.GetSection("JwtSettings").GetSection("Secret").Value);
            var singingKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(key);

           var tokenHandler = new JwtSecurityTokenHandler();
            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject = new ClaimsIdentity(new[]
                    {
                        new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                        new Claim(JwtRegisteredClaimNames.GivenName, user.Firstname),
                        new Claim(JwtRegisteredClaimNames.FamilyName, user.Surname),
                        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                        new Claim(JwtRegisteredClaimNames.Email, user.Email),
                        new Claim("id", user.Id.ToString())
                    }),
                Expires = DateTime.UtcNow.AddHours(2),
                SigningCredentials = new SigningCredentials(singingKey, SecurityAlgorithms.HmacSha256)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
Run Code Online (Sandbox Code Playgroud)

这个令牌回到我的Swagger前端,看起来还可以。

我大张旗鼓的回应:

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZUBoZXJlLmNvbSIsImdpdmVuX25hbWUiOiJDcmFpZyIsImZhbWlseV9uYW1lIjoiU21pdGgiLCJqdGkiOiI2ZWJkYjk4MC1iZWM0LTQzMTctOTkwYy1kN2Q3Mzk4MmY3Y2QiLCJlbWFpbCI6Im1lQGhlcmUuY29tIiwiaWQiOiIzMjA3YWZkOC1kMTU5LTQwNTgtYmVlNS1kZmRmYzBhYzBlODgiLCJuYmYiOjE1NjM4NzI4ODYsImV4cCI6MTU2Mzg4MDA4NiwiaWF0IjoxNTYzODcyODg2fQ.FGuc5qU-3QoIJBodYf6yi3Wi9Q9RS2kdp0NHaCrplaY"
}
Run Code Online (Sandbox Code Playgroud)

我在jwt.ms中验证了这一点:

在此处输入图片说明

因此,在这一点上,我已经生成了一个有效的JWT(我认为)。

我有一个测试端点。我在Swagger中“授权”(单击“授权”,键入“ Bearer”并粘贴令牌。

当我执行“ Autorize”端点时,我得到了这个

卷曲-X GET “ https://开头本地主机:44370 / API /账户 ” -H “接受:应用/ JSON” -H “授权:承载eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZUBoZXJlLmNvbSIsImdpdmVuX25hbWUiOiJDcmFpZyIsImZhbWlseV9uYW1lIjoiU21pdGgiLCJqdGkiOiI2ZWJkYjk4MC1iZWM0LTQzMTctOTkwYy1kN2Q3Mzk4MmY3Y2QiLCJlbWFpbCI6Im1lQGhlcmUuY29tIiwiaWQiOiIzMjA3YWZkOC1kMTU5LTQwNTgtYmVlNS1kZmRmYzBhYzBlODgiLCJuYmYiOjE1NjM4NzI4ODYsImV4cCI6MTU2Mzg4MDA4NiwiaWF0IjoxNTYzODcyODg2fQ.FGuc5qU-3QoIJBodYf6yi3Wi9Q9RS2kdp0NHaCrplaY”

这似乎表明它发送了JWT。

但是,我也收到401响应:

date: Tue, 23 Jul 2019 09:12:20 GMT 
 server: Microsoft-IIS/10.0 
 status: 401 
 www-authenticate: Bearer 
 x-powered-by: ASP.NET 
 x-sourcefiles: =?UTF-8?B?QzpcU3RvcmFnZVxTb2Z0d2FyZSBSZXBvc2l0b3JpZXNcUGVyc29uYWxcQWNjdUZpbmFuY2VWMkJhY2tlbmRcQWNjdUZpbmFuY2UgQmFja2VuZFxBUElcYXBpXGFjY291bnRz?= 
Run Code Online (Sandbox Code Playgroud)

我不确定如何调试它。我显然在某处有代码问题,但无法在哪里解决。令牌似乎生成。但是验证失败。谁能发现问题或告诉我在哪里可以调试为什么要购买401?

Ste*_*fan 5

您已经在那里,但是curl有错别字,请更改AuthorisationAuthorization

curl -X GET“ https:// localhost:44370 / api / accounts ” -H“接受:application / json” -H“授权:Bearer eyJ .....