1 Answer
- Newest
- Most votes
- Most comments
1
Hi.
I'm not sure if that is the proper way for implementing a custom authorizer. We have implemented several custom authorizers for API Gateway and Cognito pool. All of them use the JWT library for this purpose. Please take a look at the following code in order to validate, decode and get claims for a Cognito token:
import java.util.Map;
import com.auth0.jwt.interfaces.Claim;
/**
* Parses an AWS Cognito token, verifies it and returns claims found.
*
*
*/
public interface AwsCognitoTokenParser {
Map<String, Claim> parse(String token, String tokenUse);
}
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
/**
* {@link AwsCognitoTokenParser} implementation.
*
* @see https://stackoverflow.com/questions/43010211/verify-aws-id-token-on-java
*
*
*/
public class AwsCognitoTokenParserImpl implements AwsCognitoTokenParser {
private static final Logger logger = LoggerFactory.getLogger(AwsCognitoTokenParserImpl.class);
private final Algorithm algorithm;
private final String iss;
public AwsCognitoTokenParserImpl(final String awsRegion, final String awsCognitoPoolId) {
this(new AwsCognitoRSAKeyProviderImpl(awsRegion, awsCognitoPoolId));
}
public AwsCognitoTokenParserImpl(final UrlRSAKeyProvider urlRsaKeyProvider) {
algorithm = Algorithm.RSA256(urlRsaKeyProvider);
iss = urlRsaKeyProvider.getIssuerUrl();
}
@Override
public Map<String, Claim> parse(final String token, final String tokenUse) {
logger.trace("Parsing token {} for token use {}. Expected issuer is {}...", token, tokenUse, iss);
final JWTVerifier verifier = JWT.require(algorithm).withIssuer(iss).withClaim("token_use", tokenUse).build();
final DecodedJWT jwt = verifier.verify(token);
logger.trace("Parsed token. Claims are {}", jwt.getClaims());
return jwt.getClaims();
}
}
import com.auth0.jwt.interfaces.RSAKeyProvider;
/**
* {@link RSAKeyProvider} specialization obtaining the keys from an url. The issuer url is exposed too.
*
*
*/
public interface UrlRSAKeyProvider extends RSAKeyProvider {
String getIssuerUrl();
String getKeysUrl();
}
import java.net.MalformedURLException;
import java.net.URL;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwk.Jwk;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.JwkProviderBuilder;
import cloud.plexo.neuron.customer.realtime.api.authorizer.exception.NeuronCustomerRealtimeApiAuthorizerException;
/**
* RSAKeyProvider implementation for AWS Cognito keys.
*
* @see https://stackoverflow.com/questions/48356287/is-there-any-java-example-of-verification-of-jwt-for-aws-cognito-api
*
*
*/
public class AwsCognitoRSAKeyProviderImpl implements UrlRSAKeyProvider {
private static final String COGNITO_POOL_KEYS_URL_TEMPLATE = "https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json";
private static final String COGNITO_POOL_ISSUER_URL_TEMPLATE = "https://cognito-idp.%s.amazonaws.com/%s";
private static final Logger logger = LoggerFactory.getLogger(AwsCognitoRSAKeyProviderImpl.class);
private final String keysUrl;
private final String issuerUrl;
private final URL awsKidStoreUrl;
private Optional<JwkProvider> jwkProvider = Optional.empty();
public AwsCognitoRSAKeyProviderImpl(final String awsRegion, final String awsCognitoPoolId) {
keysUrl = String.format(COGNITO_POOL_KEYS_URL_TEMPLATE, awsRegion, awsCognitoPoolId);
issuerUrl = String.format(COGNITO_POOL_ISSUER_URL_TEMPLATE, awsRegion, awsCognitoPoolId);
try {
this.awsKidStoreUrl = new URL(keysUrl);
} catch (final MalformedURLException e) {
logger.error("Exception thrown constructing URL", e);
throw new RuntimeException(String.format("Invalid URL provided, URL=%s", keysUrl));
}
}
@Override
public String getIssuerUrl() {
return issuerUrl;
}
@Override
public String getKeysUrl() {
return keysUrl;
}
@Override
public RSAPrivateKey getPrivateKey() {
return null;
}
@Override
public String getPrivateKeyId() {
return null;
}
@Override
public RSAPublicKey getPublicKeyById(final String kid) {
try {
if (!jwkProvider.isPresent()) {
jwkProvider = Optional.of(new JwkProviderBuilder(awsKidStoreUrl).build());
}
final Jwk jwk = jwkProvider.get().get(kid);
return (RSAPublicKey) jwk.getPublicKey();
} catch (final Exception e) {
logger.error("Exception thrown recovering JWT kid {} from store {}", kid, awsKidStoreUrl);
throw new RuntimeException(
String.format("Failed to get JWT kid=%s from AWS kid store =%s", kid, awsKidStoreUrl));
}
}
}
Please, take a look at the referenced Stackoverflow post.
Hope this may help.
Best regards,
answered 3 years ago
Relevant content
- asked 3 years ago
- Accepted Answerasked a year ago
- AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 4 months ago
- AWS OFFICIALUpdated 4 months ago
- AWS OFFICIALUpdated 2 years ago