2016-10-13 97 views
1

我正在使用AWS Cogito服務從Cognito使用AWS Java SDK獲取用戶憑據。Java:未授權執行sts:AssumeRoleWithWebIdentity認證用戶池

我跟着 https://mobile.awsblog.com/post/TxBVEDL5Z8JKAC/Use-Amazon-Cognito-in-your-website-for-simple-AWS-authentication寫代碼來認證使用認知用戶池的用戶。

在編寫代碼之前,我配置了cognito用戶池,並將其命名爲demo,其中包含以下池配置字段。

Pool Id us-east-1_GUbY6qQ1v 
Pool ARN arn:aws:cognito-idp:us-east-1:049428796662:userpool/us-east-1_GUbY6qQ1v 

我使用上面的身份池創建來迎合聯合身份池,可以在附加圖片中看到。 Federated Identities User Pool

現在回到代碼中,我編寫了以下函數來檢索用戶身份並對其進行緩存,以便如果相同身份登錄,則不會重複調用GetID()函數。

public UserIdentity getUserIdentity(User user) throws AuthorizationException { 
if (user == null || user.getUsername() == null || user.getUsername().trim().equals("")) { 
    throw new AuthorizationException("Invalid user"); 
} 
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(new AnonymousAWSCredentials()); 

GetIdRequest idRequest = new GetIdRequest(); 
idRequest.setAccountId(CognitoConfiguration.AWS_ACCOUNT_ID); 
idRequest.setIdentityPoolId(CognitoConfiguration.IDENTITY_POOL_ID); 

GetIdResult idResp = identityClient.getId(idRequest); 

if (idResp == null) { 
    throw new AuthorizationException("Empty GetOpenIdToken response"); 
} 

GetOpenIdTokenRequest tokenRequest = new GetOpenIdTokenRequest(); 
tokenRequest.setIdentityId(idResp.getIdentityId()); 

GetOpenIdTokenResult tokenResp = identityClient.getOpenIdToken(tokenRequest); 
UserIdentity identity = new UserIdentity(); 
identity.setIdentityId(idResp.getIdentityId()); 
identity.setOpenIdToken(tokenResp.getToken()); 
return identity; 

}

用戶類包含與getOpenIdToken領域的身份,這個令牌則檢索,要求從cognito憑證時。

public AWSSessionCredentials getUserCredentials(User user) throws AuthorizationException { 
if (user == null || user.getCognitoIdentityId() == null || user.getCognitoIdentityId().trim().equals("")) { 
    throw new AuthorizationException("Invalid user"); 
} 

AWSSecurityTokenService stsClient = new AWSSecurityTokenServiceClient(new AnonymousAWSCredentials()); 
AssumeRoleWithWebIdentityRequest stsReq = new AssumeRoleWithWebIdentityRequest(); 
stsReq.setRoleArn(user.getUserRole()); 
System.out.println("The received get open id token is: " + user.getIdentity().getOpenIdToken()); 
stsReq.setWebIdentityToken(user.getIdentity().getOpenIdToken()); 
stsReq.setRoleSessionName("FassetTestSession"); 

AssumeRoleWithWebIdentityResult stsResp = stsClient.assumeRoleWithWebIdentity(stsReq); 
Credentials stsCredentials = stsResp.getCredentials(); 

// Create the session credentials object 
AWSSessionCredentials sessionCredentials = new BasicSessionCredentials(
    stsCredentials.getAccessKeyId(), 
    stsCredentials.getSecretAccessKey(), 
    stsCredentials.getSessionToken() 
); 
// save the timeout for these credentials 
Date sessionCredentialsExpiration = stsCredentials.getExpiration(); 
return sessionCredentials; 

}

用戶類的相關部分如下。

public class User { 
    private UserIdentity identity; 
    public String getCognitoIdentityId() { 
    if (this.identity == null) { 
     return null; 
    } 
    return this.identity.getIdentityId(); 
    } 

    public void setCognitoIdentityId(String cognitoIdentityId) { 
    if (this.identity == null) { 
     this.identity = new UserIdentity(); 
    } 
    this.identity.setIdentityId(cognitoIdentityId); 
    } 

}

線AssumeRoleWithWebIdentityResult stsResp = stsClient.assumeRoleWithWebIdentity(stsReq),則返回一個403禁止誤差與下面的確切的行。

2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << "<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " <Error>[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " <Type>Sender</Type>[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " <Code>AccessDenied</Code>[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " <Message>Not authorized to perform sts:AssumeRoleWithWebIdentity</Message>[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " </Error>[\n]" 
2016-10-13 17:47:02,330 DEBUG [wire(wire:72)] http-outgoing-4 << " <RequestId>fe4edd9f-913e-11e6-85cd-45155b40299e</RequestId>[\n]" 

用戶角色的信任權限是:

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Effect": "Allow", 
     "Principal": { 
     "Federated": "cognito-identity.amazonaws.com" 
     }, 
     "Action": "sts:AssumeRoleWithWebIdentity", 
     "Condition": { 
     "StringEquals": { 
      "cognito-identity.amazonaws.com:aud": "us-east-1:xxxxxxxxxxxxxxxx" 
     }, 
     "ForAnyValue:StringLike": { 
      "cognito-identity.amazonaws.com:amr": [ 
      "accounts.google.com", 
      "graph.facebook.com", 
      "authenticated" 
      ] 
     } 
     } 
    } 
    ] 
} 

其中美國東1:XXXXXXXXXXXXXXXX是用戶身份池ID管理無論是社會以及cognito用戶池。

我已經經歷了許多這樣的博客列出了信任權限和cognito用戶池,以瞭解上述問題,但徒勞無功,如果有人能夠幫助我解決上述問題,我將非常感激。

回答

1

在呼叫GetId時,您沒有在登錄地圖中傳遞用戶池用戶的id令牌。您需要使用含令牌cognito-idp.us-east-1.amazonaws.com/us-east-1_your_user_pool_id爲重點和ID您的用戶池用戶的地圖來呼籲你GetIdRequest setLogins值

由於您尚未通過此登錄映射,因此您獲得的身份是未經身份驗證的身份,並且您只允許在您的角色策略中通過身份驗證的用戶。

另請參閱:GetId API

+0

確實。感謝您的建議。這工作! – smartinsert