c# - net - authorize roles mvc 5
La validaciĆ³n JWT de ASP.NET Core 2.0 falla con `Error de autorizaciĆ³n para el usuario:(nulo)` error (7)
Cuando se agregan autenticaciones como:
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
....
Significa que cada atributo [Autorizar] que se coloca encima de un método o una clase de controlador, intentará autenticarse contra el esquema de autenticación predeterminado (en este caso, el JwtBearer) Y NO SE CASEARÁ PARA VERIFICAR la autenticación con otros esquemas que podría ser declarado (como el esquema de cookie). Para que AuthorizeAttribute se autentique contra el esquema de cookie, debe especificarse como
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
Esto también funcionará al revés, es decir, si el esquema de la cookie es el predeterminado, el esquema JwtBearer debe declararse para la autorización de aquellos métodos o controladores que necesitarían la autenticación del token JwtBearer.
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Estoy usando la aplicación ASP.NET Core 2.0 (API web) como un emisor JWT para generar un token consumible por una aplicación móvil. Desafortunadamente, un token no pudo validar este token mientras que otro lo pudo validar (usando la misma configuración de validación dentro de la misma aplicación asp.net core 2.0).
Así que tengo un token que es válido y podría decodificarse, tiene todos los reclamos y las marcas de tiempo requeridos. Pero un punto final lo acepta, mientras que otro me da 401 errores y resultados de depuración:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Información: Error de autorización para el usuario: (nulo).
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed for user: (null).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null).
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Authorization failed for the request at filter ''Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter''.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter ''Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter''.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes ().
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action MyController.Get (WebApi) in 72.105ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyController.Get (WebApi) in 72.105ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 271.077ms 401
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 271.077ms 401
Mi configuración de validación es a continuación:
var secretKey = Configuration["Authentication:OAuth:IssuerSigningKey"];
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = Configuration["Authentication:OAuth:Issuer"],
ValidateAudience = true,
ValidAudience = Configuration["Authentication:OAuth:Audience"],
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
};
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = tokenValidationParameters;
});
Estos dos puntos finales son idénticos, solo viven en diferentes controladores, ambos marcados con el atributo Authorize
.
¿Cómo es eso posible?
En su método startup.cs ConfigureServices si agrega
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => ...
Explicación: cuando utiliza [Autorizar] en un controlador, se vincula al primer sistema de autorización de forma predeterminada.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
Con esto, está configurando su valor predeterminado para autenticación JWT Bearer.
además puedes agregar
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
esta línea es cómo evitar que no se detecten errores 404 cuando se utiliza Identity with JWTs. Si está utilizando la identidad, el DefaultChallengeScheme intentará redirigirlo a una página de inicio de sesión, que si no existe resultará en que no se encuentre un 404 en lugar del 401 deseado no autorizado. Al configurar DefaultChallengeScheme en JwtBearerDefaults.AuthenticationScheme en no autorizado, ya no intentará redirigirlo a una página de inicio de sesión.
Si está utilizando la autenticación de cookies con la autenticación JWT en la etiqueta [Autorizar] , puede especificar el esquema de autenticación que desee. por ejemplo
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Este parece ser el comportamiento que recibe cuando su JWT no se valida correctamente. Tuve este problema como resultado de escribir "Portador: (JWT)" en lugar de "Portador (JWT)" en el encabezado
La secuencia de las instrucciones add en la función de configuración es importante. Asegúrate de eso
app.UseAuthentication();
viene antes
app.UseMvc();
¿Podría haber sido este el problema?
Puedes probar esto en su lugar:
.AddJwtBearer(options =>
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = tokenValidationParameters;
});''
Yo añadí:
app.UseAuthentication();
En Startup.Configure()
y que resolvió este error para mí.
Referencia: anuncio de migración de Auth 2.0.
prueba esto en startup.cs
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(opts => ...