Use JWT (Authorization: Bearer) in Swagger in ASP.NET Core

前端 未结 7 675
闹比i
闹比i 2020-12-02 15:37

I\'m creating a REST api in ASP.NET Core 1.0. I was using Swagger to test but now I added JWT authorization for some routes. (with UseJwtBearerAuthentication)

7条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-02 16:13

    Thanks to the Pavel K.'s answer, this is the way I finally resolved this issue in ASP.NET Core 2.2 with Swagger 4.0.1.

    In the Startup.cs ConfigureServices():

    public void ConfigureServices(IServiceCollection services)
    {
        .
        .
        .
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "...", Version = "v1" });
            .
            .
            .
            c.AddSecurityDefinition("Bearer", new OAuth2Scheme
            {
                Flow = "password",
                TokenUrl = "/token"
            });
    
           // It must be here so the Swagger UI works correctly (Swashbuckle.AspNetCore.SwaggerUI, Version=4.0.1.0)
           c.AddSecurityRequirement(new Dictionary>
           {
               {"Bearer", new string[] { }}
           });
        });
        .
        .
        .
    }
    

    In the Startup.cs Configure():

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        .
        .
        .
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "...");
            // Provide client ID, client secret, realm and application name (if need)
            c.OAuthClientId("...");
            c.OAuthClientSecret("...");
            c.OAuthRealm("...");
            c.OAuthAppName("...");
        });
        .
        .
        .
    }
    

    And here is how I made an endpoint to give out a JWT token:

    [ApiController, Route("[controller]")]
    public class TokenController : ControllerBase
    {
        [HttpPost, AllowAnonymous]
        public async Task> RequestToken([FromForm]LoginRequest request)
        {
            var claims = await ValidateCredentialAndGenerateClaims(request);
    
            var now = DateTime.UtcNow;
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_setting.SecurityKey));
            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    
            var token = new JwtSecurityToken(
                issuer: _setting.Issuer,
                audience: _setting.Audience,
                claims: claims,
                notBefore: now,
                expires: now.AddMinutes(_setting.ValidDurationInMinute),
                signingCredentials: signingCredentials);
    
            return Ok(new AccessTokensResponse(token));
        }
    }
    

    All your rules and logic on validating user name and password (and/or client_id and clinet_secret) will be in ValidateCredentialAndGenerateClaims().

    If you just wonder, these are my request and response models:

    /// 
    /// Encapsulates fields for login request.
    /// 
    /// 
    /// See: https://www.oauth.com/oauth2-servers/access-tokens/
    /// 
    public class LoginRequest
    {
        [Required]
        public string grant_type { get; set; }
        public string username { get; set; }
        public string password { get; set; }
        public string refresh_token { get; set; }
        public string scope { get; set; }
    
        public string client_id { get; set; }
        public string client_secret { get; set; }
    }
    
    /// 
    /// JWT successful response.
    /// 
    /// 
    /// See: https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
    /// 
    public class AccessTokensResponse
    {
        /// 
        /// Initializes a new instance of .
        /// 
        /// 
        public AccessTokensResponse(JwtSecurityToken securityToken)
        {
            access_token = new JwtSecurityTokenHandler().WriteToken(securityToken);
            token_type = "Bearer";
            expires_in = Math.Truncate((securityToken.ValidTo - DateTime.UtcNow).TotalSeconds);
        }
    
        public string access_token { get; set; }
        public string refresh_token { get; set; }
        public string token_type { get; set; }
        public double expires_in { get; set; }
    }
    

提交回复
热议问题