Use JWT (Autorización:Portador) en Swagger en ASP.NET Core

Use JWT (Autorización:Portador) en Swagger en ASP.NET Core

Luché con el mismo problema y encontré una solución funcional en esta publicación de blog:http://blog.sluijsveld.com/28/01/2016/CustomSwaggerUIField

Todo se reduce a agregar esto en sus opciones de configuración

services.ConfigureSwaggerGen(options =>
{
   options.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
});

y el código para el filtro de operación

public class AuthorizationHeaderParameterOperationFilter : IOperationFilter
{
   public void Apply(Operation operation, OperationFilterContext context)
   {
      var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
      var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
      var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);

      if (isAuthorized && !allowAnonymous)
      {
          if (operation.Parameters == null)
             operation.Parameters = new List<IParameter>();

          operation.Parameters.Add(new NonBodyParameter
          {                    
             Name = "Authorization",
             In = "header",
             Description = "access token",
             Required = true,
             Type = "string"
         });
      }
   }
}

Luego verá un cuadro de texto de autorización adicional en su swagger donde puede agregar su token en el formato 'Bearer {jwttoken}' y debería estar autorizado en sus solicitudes de swagger.


Actualmente, Swagger tiene funcionalidad para la autenticación con token JWT y puede agregar automáticamente el token en el encabezado (estoy usando Swashbuckle.AspNetCore 1.1.0).

El siguiente código debería ayudar a lograr esto.

En Startup.ConfigureServices():

services.AddSwaggerGen(c =>
{
    // Your custom configuration
    c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
    c.DescribeAllEnumsAsStrings();
    // JWT-token authentication by password
    c.AddSecurityDefinition("oauth2", new OAuth2Scheme
    {
        Type = "oauth2",
        Flow = "password",
        TokenUrl = Path.Combine(HostingEnvironment.WebRootPath, "/token"),
        // Optional scopes
        //Scopes = new Dictionary<string, string>
        //{
        //    { "api-name", "my api" },
        //}
    });
});

Comprobar y configurar TokenUrl si su punto final es diferente.

En Startup.Configure():

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "API V1");

    // Provide client ID, client secret, realm and application name (if need)

    // Swashbuckle.AspNetCore 4.0.1
    c.OAuthClientId("swagger-ui");
    c.OAuthClientSecret("swagger-ui-secret");
    c.OAuthRealm("swagger-ui-realm");
    c.OAuthAppName("Swagger UI");

    // Swashbuckle.AspNetCore 1.1.0
    // c.ConfigureOAuth2("swagger-ui", "swagger-ui-secret", "swagger-ui-realm", "Swagger UI");
});

Si su punto final para la autenticación por token sigue el estándar OAuth2, todo debería funcionar. Pero por si acaso, he agregado una muestra de este punto final:

public class AccountController : Controller
{
    [ProducesResponseType(typeof(AccessTokens), (int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.Unauthorized)]
    [HttpPost("/token")]
    public async Task<IActionResult> Token([FromForm] LoginModel loginModel)
    {
        switch (loginModel.grant_type)
        {
            case "password":
                var accessTokens = // Authentication logic
                if (accessTokens == null)
                    return BadRequest("Invalid user name or password.");
                return new ObjectResult(accessTokens);

            case "refresh_token":
                var accessTokens = // Refresh token logic
                if (accessTokens == null)
                    return Unauthorized();
                return new ObjectResult(accessTokens);

            default:
                return BadRequest("Unsupported grant type");
        }
    }
}

public class LoginModel
{
    [Required]
    public string grant_type { get; set; }

    public string username { get; set; }
    public string password { get; set; }
    public string refresh_token { get; set; }
    // Optional
    //public string scope { get; set; }
}

public class AccessTokens
{
    public string access_token { get; set; }
    public string refresh_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
}

Para ampliar la respuesta de HansVG que funcionó para mí (gracias) y dado que no tengo suficientes puntos de contribución, no puedo responder directamente a la pregunta emseetea. Una vez que tenga el cuadro de texto Autorización, deberá llamar al punto final que genera el token que estará fuera de su área de puntos finales que debe [Autorizar].

Una vez que haya llamado a ese punto final para generar el token desde el punto final, puede copiarlo de los resultados para ese punto final. Luego tiene el token para usar en sus otras áreas que deben [Autorizar]. Solo pégalo en el cuadro de texto. Asegúrese, como mencionó HansVG, de agregarlo en el formato correcto, que debe incluir "portador". Formato ="{token} portador".