首页 > 解决方案 > Cognito SRP 身份验证 JAVA SDK

问题描述

我正在尝试使用 Cognito 对 Java 应用程序进行身份验证。我已经为 python 使用了运行良好的保证库。但我现在想在java中做同样的事情。

我的 Python 函数用于使用授权库进行身份验证

def SRPauthentication(organizationAdmin,
                     password,
                     pool_id,
                     client_id,
                     client):
    aws = AWSSRP(username=organizationAdmin,
                 password=password,
                 pool_id=pool_id,
                 client_id=client_id,
                 client=client)
    tokens = aws.authenticate_user()
    authorization_token= tokens['AuthenticationResult']['IdToken']
    return authorization_token 

有了这个,我可以轻松访问一些安全的 API。现在我想对 Java 做同样的事情,但我遇到了问题。

到目前为止,这是我的解决方案是这种方法:

  public static void GetCreds()
      {

          AWSCognitoIdentityProvider identityProvider = AWSCognitoIdentityProviderClientBuilder.defaultClient();
          AdminInitiateAuthRequest adminInitiateAuthRequest = new AdminInitiateAuthRequest().
                  withAuthFlow(AuthFlowType.USER_SRP_AUTH).
                  withClientId("234234234234").withUserPoolId("eu-central-1_sdfsdfdsf")
                  .addAuthParametersEntry("USERNAME", "UserK").
                   addAuthParametersEntry("PASSWORD","#######);

          adminInitiateAuthRequest.getAuthFlow();
          AdminInitiateAuthResult adminInitiateAuth = identityProvider.adminInitiateAuth(adminInitiateAuthRequest);
            System.out.println(adminInitiateAuth.getAuthenticationResult().getIdToken());
      }

当我运行它时,我得到一个异常:

Exception in thread "main" `com.amazonaws.services.cognitoidp.model.AWSCognitoIdentityProviderException: User: arn:aws:iam::XXXXXXXXXXXXXXXXX:user/khan is not authorized to perform: cognito-idp:AdminInitiateAuth on resource: arn:aws:cognito-idp:eu-central-1:XXXXXXXX:userpool/eu-central-1_XXXXXXX with an explicit deny (Service: AWSCognitoIdentityProvider; Status Code: 400; Error Code: AccessDeniedException; Request ID: 21be0b8e-adec-11e8-ad45-234234234)`

它说我无权执行这种指令。所以我想我做的事情通常是错误的。因为它与我的 python 代码和 Java 一起工作,所以它可以从凭据中识别我的用户名。Cognito 调用实际上应该独立于我的 aws 凭据/用户帐户,对吗?

如何使用 Java 向 Cognito 进行身份验证以获取令牌以访问安全的 aws 服务?

编辑:

  AWSCognitoIdentityProvider identityProvider = AWSCognitoIdentityProviderClientBuilder.standard()
              .build();
      InitiateAuthRequest adminInitiateAuthRequest = new InitiateAuthRequest()
              .withAuthFlow(AuthFlowType.USER_SRP_AUTH)
              .withClientId("XXXXXXXXXXXXXXXXX")
              .addAuthParametersEntry("USERNAME", "user").
               addAuthParametersEntry("PASSWORD","za$Lwn")
              .addAuthParametersEntry("SRP_A",new AuthenticationHelper("eu-central-1XXXXXXXXX").getA().toString(16));

      adminInitiateAuthRequest.getAuthFlow();
      InitiateAuthResult adminInitiateAuth = identityProvider.initiateAuth(adminInitiateAuthRequest);
      System.out.println(adminInitiateAuth);

我将 AdminInitateAuthRequest 更改为 InitateAuthRequest。之后我有错误丢失 SRP_A 参数,我在这里用一个类似的问题以某种方式修复了 现在我收到了这个:

{ChallengeName: PASSWORD_VERIFIER,ChallengeParameters: {SALT=877734234324234ed68300f39bc5b, SECRET_BLOCK=lrkwejrlewrjlewkjrewlrkjwerlewkjrewlrkjewrlkewjrlewkrjZ+Q==, USER_ID_FOR_SRP=user, USERNAME=user, SRP_B=43ecc1lwkerjwelrkjewlrjewrlkewjrpoipweoriwe9r873jr34h9r834hr3455f7d079d71e5012f1623ed54dd10b832792dafa3438cca3f59c0f462cbaee255d5b7c2werwerwerkjweorkjwerwerewrf5020e4f8b5452f3b89caef4a797456743602b80b5259261f90e52374adc06b456521a9026cce9c1cbe8b9ffd6040e8c1589d35546861422110ac7e38c1c93389b802a03e3e2e4a50e75d088275195f836f66e25f1a431dd56bb2},}

我已经用所有键缩短了结果,但下一步该怎么做?

标签: javaamazon-web-servicesamazon-cognitoaws-java-sdksrp-protocol

解决方案


最后我可以用这个代码类解决它。SRP 身份验证涉及多个挑战。InitiateAuthRequest 是第一个必要的请求。

这个类似的问题帮助了我: stackoverflow stackoverfow

String PerformSRPAuthentication(String username, String password) {
    String authresult = null;

    InitiateAuthRequest initiateAuthRequest = initiateUserSrpAuthRequest(username);
    try {
        AnonymousAWSCredentials awsCreds = new AnonymousAWSCredentials();
        AWSCognitoIdentityProvider cognitoIdentityProvider = AWSCognitoIdentityProviderClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .withRegion(Regions.fromName(this.region))
                .build();
        InitiateAuthResult initiateAuthResult = cognitoIdentityProvider.initiateAuth(initiateAuthRequest);
        if (ChallengeNameType.PASSWORD_VERIFIER.toString().equals(initiateAuthResult.getChallengeName())) {
            RespondToAuthChallengeRequest challengeRequest = userSrpAuthRequest(initiateAuthResult, password);
            RespondToAuthChallengeResult result = cognitoIdentityProvider.respondToAuthChallenge(challengeRequest);
            //System.out.println(result);
            System.out.println(CognitoJWTParser.getPayload(result.getAuthenticationResult().getIdToken()));
            authresult = result.getAuthenticationResult().getIdToken();
        }
    } catch (final Exception ex) {
        System.out.println("Exception" + ex);

    }
    return authresult;
}


 private InitiateAuthRequest initiateUserSrpAuthRequest(String username) {

    InitiateAuthRequest initiateAuthRequest = new InitiateAuthRequest();
    initiateAuthRequest.setAuthFlow(AuthFlowType.USER_SRP_AUTH);
    initiateAuthRequest.setClientId(this.clientId);
    //Only to be used if the pool contains the secret key.
    //initiateAuthRequest.addAuthParametersEntry("SECRET_HASH", this.calculateSecretHash(this.clientId,this.secretKey,username));
    initiateAuthRequest.addAuthParametersEntry("USERNAME", username);
    initiateAuthRequest.addAuthParametersEntry("SRP_A", this.getA().toString(16));
    return initiateAuthRequest;
}

推荐阅读