Jwt 代码在 .NET Core 2 上不起作用

Posted

技术标签:

【中文标题】Jwt 代码在 .NET Core 2 上不起作用【英文标题】:Jwt Code not working on .NET Core 2 【发布时间】:2018-08-28 04:05:06 【问题描述】:

我正在尝试学习如何将 Jwt 添加到我正在处理的 API 中。 我已经跟进了这个introduction 如何使用 Jwt 构建 API。 我的应用程序现在确实生成了 Jwt 代码,但是当我调用 API 的 Authorize 部分时,使用 Post man 使用 Authorization 标头和 Bearer,我得到 401 Unauthrized 响应。 我的代码是

StattUp.cs

public class Startup

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    


        /**/
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            
                options.TokenValidationParameters = new TokenValidationParameters
                
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                ;
            );

        /**/
        services.AddMvc();
    

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

        app.UseMvc();
        app.UseAuthentication();

    

TokenController.cs

public class TokenController : Controller

    private IConfiguration _config;
    public TokenController (IConfiguration config)
    
        _config = config;
    

    [AllowAnonymous]
    [HttpPost]
    public IActionResult CreateToken (LoginModel login)
    
        IActionResult response = Unauthorized();
        var user = Authenticate(login); 
        if (user != null)
        
            var tokenString = BuildToken(user);
            response = Ok(new token = tokenString );
        
        return response;
    
    private string BuildToken (UserModel user)
    
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(_config["Jwt:Issuer"],
            _config["Jwt:Issuer"],
            expires: DateTime.Now.AddHours(30),
            signingCredentials: creds
            );

        return new JwtSecurityTokenHandler().WriteToken(token);
    

    private UserModel Authenticate(LoginModel login)
    
        UserModel user = null;
        if (login.Username != null && login.Password != null)
        
            if (login.Username.ToLower() == "r" && login.Password.ToLower() == "d")
            
                user = new UserModel  Name = "R D", Email = "test@yahoo.com" ;

            
        
        return user;
    









    public class LoginModel
    
        public string Username  get; set; 
        public string Password  get; set; 
    

    private class UserModel
    
        public string Name  get; set; 
        public string Email  get; set; 
        public DateTime Birthdate  get; set; 
    


BooksController.cs

 public class BooksController : Controller

    [HttpGet, Authorize]
    public IEnumerable<Book> Get()
    
        var currentUser = HttpContext.User;
        var result = new Book[] 
                new Book  Author = "Ray Bradbury",Title = "Fahrenheit 451" ,
                new Book  Author = "Gabriel García Márquez", Title = "One Hundred years of Solitude" ,
                new Book  Author = "George Orwell", Title = "1984" ,
                new Book  Author = "Anais Nin", Title = "Delta of Venus" , AgeRestriction = true

        ;
        return result; 
    


public class Book


    public string Author  get; set; 
    public string Title  get; set; 
    public bool AgeRestriction  get; set; 

Appsetting.json

  
  "Logging": 
    "IncludeScopes": false,
    "Debug": 
      "LogLevel": 
        "Default": "Warning"
      
    ,
    "Console": 
      "LogLevel": 
        "Default": "Warning"
      
    
  ,
  "Jwt": 
    "Key": "veryVerySecretKey",
    "Issuer": "http://localhost:50431/"
  

附言 我试过打电话给http://localhost:50431/api/books 使用 Postman 和

授权:承载eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MjE1NzgxMTgsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTA0MzEvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo1MDQzMS8ifQ.D4o7ruHv4d6QFKQvOFTmtKwlbIgvTF-PnYJXUdaRCg8 P>

我没有运气,所以任何帮助将不胜感激

【问题讨论】:

Authorization: 和 Bearer 之间有空格吗?我认为您将需要它们之间的空间,例如授权:不记名…… @SimplyGed 我用 Space 和没有空间都试过了,都返回 401 【参考方案1】:

这是一个非常常见的错误。您应该在 MVC 中间件之前添加身份验证中间件。这里的顺序真的很重要。

所以要解决问题,请按以下方式更改Startup.Configure 方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseAuthentication();
    app.UseMvc();

查看以下文章了解更多详情:

ASP.NET Core Middleware - Ordering Why UseAuthentication must be before UseMvc in NET Core 2.0

【讨论】:

以上是关于Jwt 代码在 .NET Core 2 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core 2 JWT,Angular 2 通过角色授权不起作用

在 ASP .Net Core 2.2 中添加 JWT 令牌后授权不起作用

使用 System.IdentityModel.Tokens.Jwt 从 1.1 迁移到 2.0 后,JWTAuthentication 在 asp.net core 2.0 中不起作用 - 5.1.

JWT不记名令牌授权不起作用asp net core web api

ASP.NET Core WebApi Jwt 基于角色的授权不起作用

ASP.Net Core - 使用 WebAPI 和 MVC 前端的 JWT 身份验证不起作用