Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有针对aws cognito API的JWT验证的java示例?_Java_Amazon Web Services_Jwt_Aws Cognito - Fatal编程技术网

是否有针对aws cognito API的JWT验证的java示例?

是否有针对aws cognito API的JWT验证的java示例?,java,amazon-web-services,jwt,aws-cognito,Java,Amazon Web Services,Jwt,Aws Cognito,我使用的是aws cognito用户池,在用户登录后,我在单页应用程序中获得了一个id令牌,这是预期的,然后对于每个请求,我需要在我的后端rest API中验证id令牌,它是java的,aws文档没有太多提到如何做 有什么例子吗 混淆包括: id令牌似乎不仅仅是一个签名的JWT,它也是加密的,当使用nimbus库时,我需要为加密的JWT指定一个秘密,我在哪里可以获得这个秘密?我的理解是这应该来自aws,我是否需要下载一些东西然后放入jvm密钥库 有一个著名的jwts.json可以从aws下载,它

我使用的是aws cognito用户池,在用户登录后,我在单页应用程序中获得了一个id令牌,这是预期的,然后对于每个请求,我需要在我的后端rest API中验证id令牌,它是java的,aws文档没有太多提到如何做

有什么例子吗

混淆包括:

  • id令牌似乎不仅仅是一个签名的JWT,它也是加密的,当使用nimbus库时,我需要为加密的JWT指定一个秘密,我在哪里可以获得这个秘密?我的理解是这应该来自aws,我是否需要下载一些东西然后放入jvm密钥库

  • 有一个著名的jwts.json可以从aws下载,它看起来像:

  • `

    `

    如何理解这一点,每个属性用于什么?用户池中的每个用户都代表一个密钥吗

  • 是否有任何用于aws cognito服务验证的示例java代码,我可以使用aws sdk还是必须使用像nimbus这样的库来自己进行验证

  • 您可以使用标准验证令牌。此外,验证JWT令牌还涉及几个步骤。虽然我找不到Java示例,但下面是一个NodeJS示例,它将解释验证过程

    const jwt = require('jsonwebtoken');
    const jwtToken = "sampletoken****";
    const jwkPem = { "alg" : "RS256", "kid" : "samplekid****" }
    
    var decodedJwt = jwt.decode(jwtToken, {complete: true});
    
    //Fail if the token is not jwt
    if (!decodedJwt) {
        console.log("Not a valid JWT token");
        return;
    }
    
    //Fail if token is not from your User Pool
    if (decodedJwt.payload.iss != iss) {
        console.log("invalid issuer");
        return;
    }
    
    //Reject the jwt if it's not an 'Access Token'
    if (!(decodedJwt.payload.token_use == 'id' || 
        decodedJwt.payload.token_use == 'access')) {
        console.log("token_use is invalid");
        return;
    }
    
    //Get the kid from the token and retrieve corresponding PEM
    var kid = decodedJwt.header.kid;
    var pem = jwkPem[kid];
    if (!pem) {
        console.log("Invalid access token");
        return;
    }
    
    //Verify the signature of the JWT token to ensure it's really coming from your User Pool and that it has not expired
    jwt.verify(jwtToken, pem, { issuer: iss, maxAge: 3600000}, function(err, payload) {
      if(err) {
        console.log(err);
      } else {
        console.log("Authorization successful");
      }
    });
    

    至于这个秘密,你指的是特定于应用程序客户端的吗?这是您在创建和安装应用程序客户端时得到的。转到AWS控制台和Cognito。选择适当的用户池,单击应用程序客户端。这是一个秘密,但你必须确保在创建应用程序客户端时选择创建它的选项(或者不使用)。否则,就做一个新的。

    我只是挣扎着想和大家分享一下

    如果使用maven,请将其添加到pom.xml中

    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>jwks-rsa</artifactId>
        <version>0.4.0</version>
    </dependency>
    
    创建一个实现RSAKeyProvider的类

    import com.auth0.jwk.JwkException;
    import com.auth0.jwk.JwkProvider;
    import com.auth0.jwk.JwkProviderBuilder;
    import com.auth0.jwt.interfaces.RSAKeyProvider;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    public class AwsCognitoRSAKeyProvider implements RSAKeyProvider {
    
        private final URL aws_kid_store_url;
        private final JwkProvider provider;
    
        public AwsCognitoRSAKeyProvider(String aws_cognito_region, String aws_user_pools_id) {
            String url = String.format("https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json", aws_cognito_region, aws_user_pools_id);
            try {
                aws_kid_store_url = new URL(url);
            } catch (MalformedURLException e) {
                throw new RuntimeException(String.format("Invalid URL provided, URL=%s", url));
            }
            provider = new JwkProviderBuilder(aws_kid_store_url).build();
        }
    
    
        @Override
        public RSAPublicKey getPublicKeyById(String kid) {
            try {
                return (RSAPublicKey) provider.get(kid).getPublicKey();
            } catch (JwkException e) {
                throw new RuntimeException(String.format("Failed to get JWT kid=%s from aws_kid_store_url=%s", kid, aws_kid_store_url));
            }
        }
    
        @Override
        public RSAPrivateKey getPrivateKey() {
            return null;
        }
    
        @Override
        public String getPrivateKeyId() {
            return null;
        }
    }
    
    现在,您可以通过以下方式验证您的令牌

    String aws_cognito_region = "us-east-1"; // Replace this with your aws cognito region
    String aws_user_pools_id = "us-east-1_7DEw1nt5r"; // Replace this with your aws user pools id
    RSAKeyProvider keyProvider = new AwsCognitoRSAKeyProvider(aws_cognito_region, aws_user_pools_id);
    Algorithm algorithm = Algorithm.RSA256(keyProvider);
    JWTVerifier jwtVerifier = JWT.require(algorithm)
        //.withAudience("2qm9sgg2kh21masuas88vjc9se") // Validate your apps audience if needed
        .build();
    
    String token = "eyJraWQiOiJjdE.eyJzdWIiOiI5NTMxN2E.VX819z1A1rJij2"; // Replace this with your JWT token
    jwtVerifier.verify(token);
    
    请注意,JwkProviderBuilder将构建一个带有LRU缓存的JwkProvider,该缓存缓存从aws密钥存储库中检索到的密钥,非常整洁!可以使用生成器更改缓存规则


    [UPDATE]将创建JwkProvider移动到构造函数,因此正如@danieln所评论的那样,缓存也得到了尊重,然而,它是旧的,有几个不推荐的项目,它会给你一个ideahttps://aws.amazon.com/blogs/developer/building-a-serverless-developer-authentication-api-in-java-using-aws-lambda-amazon-dynamodb-and-amazon-cognito-part-2/ 或者在这里看到这篇非常精彩的相关文章,我花了几个小时试图从不同的角度实现这一点。到目前为止,我发现没有一个解决方案像这一个那么简单直接。工作起来很有魅力!非常感谢,伙计。非常感谢,我终于成功了。我必须做的两件小事是获取jwt库的更新版本,并确保jwt令牌已被删除。@AndiDev回答得很好!您不应该初始化JwkProvider一次,然后在getPublicKeyById中返回它,而不是反复初始化它吗?@danieln说得不错。感觉应该在构造函数中创建JwkProvider提供程序。否则,我想缓存就不起作用了。不再使用此代码,因此我无法验证它。如果你能验证它是否按预期工作,我可以更改答案。我验证了它,它按预期工作。
    import com.auth0.jwk.JwkException;
    import com.auth0.jwk.JwkProvider;
    import com.auth0.jwk.JwkProviderBuilder;
    import com.auth0.jwt.interfaces.RSAKeyProvider;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    public class AwsCognitoRSAKeyProvider implements RSAKeyProvider {
    
        private final URL aws_kid_store_url;
        private final JwkProvider provider;
    
        public AwsCognitoRSAKeyProvider(String aws_cognito_region, String aws_user_pools_id) {
            String url = String.format("https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json", aws_cognito_region, aws_user_pools_id);
            try {
                aws_kid_store_url = new URL(url);
            } catch (MalformedURLException e) {
                throw new RuntimeException(String.format("Invalid URL provided, URL=%s", url));
            }
            provider = new JwkProviderBuilder(aws_kid_store_url).build();
        }
    
    
        @Override
        public RSAPublicKey getPublicKeyById(String kid) {
            try {
                return (RSAPublicKey) provider.get(kid).getPublicKey();
            } catch (JwkException e) {
                throw new RuntimeException(String.format("Failed to get JWT kid=%s from aws_kid_store_url=%s", kid, aws_kid_store_url));
            }
        }
    
        @Override
        public RSAPrivateKey getPrivateKey() {
            return null;
        }
    
        @Override
        public String getPrivateKeyId() {
            return null;
        }
    }
    
    String aws_cognito_region = "us-east-1"; // Replace this with your aws cognito region
    String aws_user_pools_id = "us-east-1_7DEw1nt5r"; // Replace this with your aws user pools id
    RSAKeyProvider keyProvider = new AwsCognitoRSAKeyProvider(aws_cognito_region, aws_user_pools_id);
    Algorithm algorithm = Algorithm.RSA256(keyProvider);
    JWTVerifier jwtVerifier = JWT.require(algorithm)
        //.withAudience("2qm9sgg2kh21masuas88vjc9se") // Validate your apps audience if needed
        .build();
    
    String token = "eyJraWQiOiJjdE.eyJzdWIiOiI5NTMxN2E.VX819z1A1rJij2"; // Replace this with your JWT token
    jwtVerifier.verify(token);