본문 바로가기

AWS IoT/안드로이드 앱

[AWS IoT] 어플리케이션 (3) : CognitoCachingCredentialsProvider 객체

CognitoCredentialProvider는 Cognito ID Pool에 연결되어 STS의 "임시 자격 증명"을 관리하는 AWSCredentialsProvider 인터페이스 구현 객체입니다. 그리고 CognitoCachingCredentialProvider는 CognitoCredentialProvider 클래스를 상속하고, 네트워크 연결 횟수를 줄이기 위해 캐시를 사용하는데 이것을 위해 SharedPreferences 정도만 추가한 것으로 알고 있습니다.

 

AWSCredentialsProvider 인터페이스 구현 객체는 AWS Android SDK의 각 서비스 객체를 해당 서비스에 연결할 때 인증 수단으로 사용됩니다. 즉, STS의 "임시 자격 인증"을 원하는 서비스에 연결하는 역할을 합니다. GitHub에서 각 서비스 모듈에서  AWSCredentialsProvider 인터페이스 구현 객체가 사용되는 것을 확인할 수 있을 것입니다.

 

사용자가 Cognito에 로그인을 한다고 CognitoCredentialProvider 객체까지 자동으로 인증되지 않습니다. Cognito에 로그인한 사용자는 Cognito로 부터 토큰 집합인 세션을 CognitoUserSession 객체로 받습니다. 이 객체에서 ID 토큰을 추출하여 setLogins 메소드에 매개값으로 넣어 해당 메소드를 실행시킨 후에야, CognitoCredentialProvider 객체를 사용하여 Cognito ID Pool의 인증된 역할에 대한 "임시 자격 증명"에 접근할 수 있습니다. 코드는 다음과 같습니다. "necessary ??"로 주석처리한 부분은 개발자 포럼에서 사용해야 한다고 본 것 같은데 사용하지 않아도 정상 작동해서 필요성이 의심되는 부분 입니다.

String idToken = null;
if(currSession != null) {
    idToken = currSession.getIdToken().getJWTToken();
    if(idToken == null) {
        return false;
    }

    Map<string, string> logins = new HashMap<string, string>();
    logins.put("cognito-idp.us-east-1.amazonaws.com/" + userPoolId, idToken);
    credentialsProvider.setLogins(logins);

    // necessary ??
    Thread refresh = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                credentialsProvider.refresh();
            } catch (Exception e) {
                Log.e(TAG, "Credential refresh error.", e);
            }
        }
    });
    refresh.start();

    return true;
}

사용자가 로그인하여 Cognito로 부터 토큰 집합인 세션을 CognitoUserSession 객체를 받는 과정은 아래와 같습니다. 그냥 참고정도만 하면 될 것 같습니다. 저도 코드를 일일히 확인하지 않고 주요 클래스와 메소드들의 흐름만 확인했습니다. 

CognitoUserPool 객체에서 CognitoUser 객체를 얻어온 후 해당 객체의 getSessionInBackground 메소드에 AuthenticationHandler 객체를 매개값으로 넣어 호출합니다. CognitoUser 객체를 얻어올 때 username이 입력되는데 AuthenticationHandler 객체의 getAuthenticationDetails 메소드에 username의 password 정보가 저장되어 있습니다. 사용자는 이 password 정보를 바로 볼 수 없고, 자신이 입력한 password를 getAuthenticationDetails 메소드의 매개 객체인 AuthenticationContinuation 객체의 setAuthenticationDetails 메소드에 넣어 password가 일치하는지 확인할 수 있습니다. 사용자가 입력한 password와 Cognito에서 받은 pasword가 일치하면, AuthenticationHandler 객체의 onSuccess 메소드가 호출되고 여기서 CognitoUserSession 객체를 얻게됩니다. 위에서 언급했다시피 이 객체에서 추출된 ID 토큰은 CognitoCredentialProvider 객체 인증에 사용합니다.