简体   繁体   English

AWS Cognito JWT令牌验证

[英]AWS Cognito JWT token validation

I am trying to enforce security based on AWS Cognito JWT token, the source is at https://github.com/IxorTalk/ixortalk.aws.cognito.jwt.security.filter . 我正在尝试基于AWS Cognito JWT令牌强制实施安全性,源位于https://github.com/IxorTalk/ixortalk.aws.cognito.jwt.security.filter

But I have concern, which is per documentation http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-identity-user-pools-using-id-and-access-tokens-in-web-api 但我担心,这是根据文档http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito身份用户池使用ID和访问Web API中的令牌

It says "The ID token expires one hour after the user authenticates. You should not process the ID token in your client or web API after it has expired." 它说:“ ID令牌在用户验证后一小时后失效。过期后,您不应在客户端或Web API中处理该ID令牌。”

Which is the error I am seeing in my logs, com.nimbusds.jwt.proc.BadJWTException: Expired JWT. 这是我在日志中看到的错误com.nimbusds.jwt.proc.BadJWTException:JWT已过期。 I assume, that the JWT token has already expired, what would be my steps to successfully enforce token based authorization? 我假设JWT令牌已经过期,那么我将如何成功执行基于令牌的授权?

You need the refresh token, that helps you get new identity and access tokens. 您需要刷新令牌,以帮助您获得新的身份和访问令牌。 The Cognito JS SDK refreshes the token automatically. Cognito JS SDK自动刷新令牌。

Now in your case, seems like you need to call the RefreshToken and add a check to see if the token is expired. 现在以您的情况而言,似乎您需要调用RefreshToken并添加检查以查看令牌是否已过期。

The identity/access tokens come with a expiration time so this is something you can do locally in your application before you use them. 身份/访问令牌具有到期时间,因此您可以在使用它们之前在应用程序中对其进行本地处理。

If you are using Java, The way I have programmed is this, 如果您使用的是Java,我的编程方式就是这样,

    // Parse the Cognito Keys and get the key by kid
    // Key is just a class that is used for parsing JSON to POJO
    Key key = this.keyService.getKeyByKeyId(JWT.decode(token).getKeyId());

    // Use Key's N and E
    BigInteger modulus = new BigInteger(1, Base64.decodeBase64(key.getN()));
    BigInteger exponent = new BigInteger(1, Base64.decodeBase64(key.getE()));

    // Create a publick key
    PublicKey publicKey = null;
    try {
        publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));
    } catch (InvalidKeySpecException e) {
        // Throw error
    } catch (NoSuchAlgorithmException e) {
        // Throw error
    }

    // get an algorithm instance
    Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, null);

    // I verify ISS field of the token to make sure it's from the Cognito source
    String iss = String.format("https://cognito-idp.%s.amazonaws.com/%s", REGION, POOL_ID);

    JWTVerifier verifier = JWT.require(algorithm)
            .withIssuer(iss)
            .withClaim("token_use", "id") // make sure you're verifying id token
            .build();

    // Verify the token
    DecodedJWT jwt = verifier.verify(token);

    // Parse various fields
    String username = jwt.getClaim("sub").asString();
    String email = jwt.getClaim("email").asString();
    String phone = jwt.getClaim("phone_number").asString();
    String[] groups = jwt.getClaim("cognito:groups").asArray(String.class);

I am using this repo to verify and parsing of the tokens, 我正在使用此仓库来验证和解析令牌,

    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.4.1</version>
    </dependency>

Make sure you are importing the following, 确保您要导入以下内容,

    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.exceptions.JWTDecodeException;
    import com.auth0.jwt.interfaces.DecodedJWT;

    import java.math.BigInteger;
    import java.security.KeyFactory;
    import java.security.NoSuchAlgorithmException;
    import java.security.PublicKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.RSAPublicKeySpec;
    import org.apache.commons.codec.binary.Base64;

If the token is expired, it won't be varified. 如果令牌已过期,它将不会被更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM