AWS Cognito JWT 令牌验证
Posted
技术标签:
【中文标题】AWS Cognito JWT 令牌验证【英文标题】:AWS Cognito JWT token validation 【发布时间】:2018-03-07 21:02:16 【问题描述】:我正在尝试基于 AWS Cognito JWT 令牌强制执行安全性,来源位于 https://github.com/IxorTalk/ixortalk.aws.cognito.jwt.security.filter。
但我担心,这是每个文档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
上面写着“ID 令牌在用户验证后一小时过期。过期后,您不应在客户端或 Web API 中处理 ID 令牌。”
我在日志中看到的错误是什么, com.nimbusds.jwt.proc.BadJWTException:过期的 JWT。我假设 JWT 令牌已经过期,我将如何成功执行基于令牌的授权?
【问题讨论】:
你使用刷新令牌来获取新的id+刷新+访问令牌。 【参考方案1】:如果你使用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);
我正在使用这个 repo 来验证和解析令牌,
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.1</version>
</dependency>
确保您正在导入以下内容,
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;
如果令牌已过期,则不会更改。
【讨论】:
【参考方案2】:您需要刷新令牌,它可以帮助您获得新的身份和访问令牌。 Cognito JS SDK 会自动刷新令牌。
现在在您的情况下,您似乎需要调用 RefreshToken 并添加检查以查看令牌是否已过期。
身份/访问令牌带有过期时间,因此您可以在使用它们之前在应用程序中本地执行此操作。
【讨论】:
嗨,cognito 返回刷新令牌和其他数据。我是否需要不断检查 id 令牌是否过期并在过期时请求它?以上是关于AWS Cognito JWT 令牌验证的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Go 中验证来自 AWS Cognito 的 JWT 令牌?
AWS Cognito 如何验证我自己的 IdP 颁发的身份令牌?
我是不是需要在 Lambda 和 API 网关中验证 AWS Cognito 令牌?