Te recomendamos que pruebes esta solución en un entorno controlado antes de pasarlo a producción, un saludo.
Solución:
La respuesta radica principalmente en definir correctamente el TokenValidationParameters.IssuerSigningKeyResolver
(parámetros, etc. vistos aquí: https://docs.microsoft.com/en-us/dotnet/api/microsoft.identitymodel.tokens.issuersigningkeyresolver?view=azure-dotnet).
Esto es lo que le dice a .NET Core contra qué verificar el JWT enviado. También hay que indicarle dónde encontrar la lista de keys. Uno no necesariamente puede codificar el key establecido, ya que AWS lo rota a menudo.
Una forma de hacerlo sería buscar y serializar la lista desde la URL dentro del IssuerSigningKeyResolver
método. El conjunto .AddJwtBearer()
podría verse algo como esto:
Método Startup.cs ConfigureServices():
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
// serialize the result
var keys = JsonConvert.DeserializeObject(json).Keys;
// cast the result to be the type expected by IssuerSigningKeyResolver
return (IEnumerable)keys;
,
ValidIssuer = "https://cognito-idp.region.amazonaws.com/pool ID",
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = "Cognito AppClientID",
ValidateAudience = true
;
);
Si usa una biblioteca JS como AWS Amplify, puede ver parámetros como el ValidIssuer
y ValidAudience
en la consola de su navegador observando el resultado de Auth.currentSession()
Una solicitud de recuperación REST de un cliente JS a una API web de .NET Core que utiliza la autenticación JWT lograda anteriormente, así como el uso de la [Authorize]
La etiqueta en su controlador podría verse así:
Cliente JS usando el paquete de nodos @aws-amplify/auth:
// get the current logged in user's info
Auth.currentSession().then((user) =>
fetch('https://localhost:5001/api/values',
method: 'GET',
headers:
// get the user's JWT token given to it by AWS cognito
'Authorization': `Bearer $user.signInUserSession.accessToken.jwtToken`,
'Content-Type': 'application/json'
).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.error(e))
)
La respuesta proporcionada aquí solo es necesaria si necesita un control más detallado sobre la validación.
De lo contrario, el siguiente código es suficiente para validar jwt.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.Authority = "yourAuthorizationServerAddress";
options.Audience = "yourAudience";
);
Okta tiene un buen artículo sobre esto. https://developer.okta.com/blog/2018/03/23/token-autenticación-aspnetcore-guía-completa
Cuando el middleware JwtBearer maneja una solicitud por primera vez, intenta recuperar algunos metadatos del servidor de autorización (también llamado autoridad o emisor). Estos metadatos, o documento de descubrimiento en la terminología de OpenID Connect, contienen el público keys y otros detalles necesarios para validar tokens. (¿Tiene curiosidad por el aspecto de los metadatos? Aquí hay un documento de descubrimiento de ejemplo).
Si el middleware JwtBearer encuentra este documento de metadatos, se configura automáticamente. ¡Bastante ingenioso!
Te mostramos las reseñas y valoraciones de los lectores
Tienes la opción de añadir valor a nuestra información cooperando tu experiencia en las explicaciones.