使用Android

时间:2016-02-02 16:09:47

标签: android amazon-web-services aws-sdk

我正在尝试使用开发人员身份验证提供程序登录我的Android应用程序,基于此演示:https://github.com/awslabs/aws-sdk-android-samples/tree/master/CognitoSyncDemo。我通过我们自己的后端成功登录获得了idToken,随后获得了访问我们AWS数据库的会话凭据。然后,我使用这些凭据对数据库进行POST。

但这只能工作一次,现在我再也无法通过,没有更改任何代码。我还通过http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk.html使用生成的SDK。我不确定这是否会导致任何错误。

这是我的DeveloperAuthenticationProvider:

public class AuthenticationProvider extends
    AWSAbstractCognitoDeveloperIdentityProvider {

private static final String TAG = AuthenticationProvider.class.getSimpleName();

private static SocializeClient mSocializeClient;

private static final String developerProvider = Constants.AWS_PROVIDER_NAME;
private static final String cognitoSampleDeveloperAuthenticationAppEndpoint = UrlEndpoints.URL_DOMAIN;

public AuthenticationProvider(Context context, String accountId, String identityPoolId, Regions region) {
    super(accountId, identityPoolId, region);

    /*
     * Initialize the client using which you will communicate with your
     * backend for user authentication.
     */
    AWSCredentialsProvider awsCredentialsProvider = new CognitoCachingCredentialsProvider(
            context,
            this,
            region
    );

    ApiClientFactory factory = new ApiClientFactory()
            .endpoint(cognitoSampleDeveloperAuthenticationAppEndpoint)
            .credentialsProvider(awsCredentialsProvider);

    mSocializeClient = factory.build(SocializeClient.class);

}

/*Only refreshes the login info, when it has expired*/

/*
 * (non-Javadoc)
 * @see com.amazonaws.auth.AWSCognitoIdentityProvider#refresh() In refresh
 * method, you will have two flows:
 */
/*
 * 1. When the app user uses developer authentication. In this case, make
 * the call to your developer backend, from where call the
 * GetOpenIdTokenForDeveloperIdentity API of Amazon Cognito service. Be sure to call update(), so as to
 * set the identity id and the token received.
 */
/*
 * 2.When the app user is not using the developer authentication, just call
 * the refresh method of the AWSAbstractCognitoDeveloperIdentityProvider
 * class which actually calls GetId and GetOpenIDToken API of Amazon
 * Cognito.
 */
@Override
public String refresh() {
    Log.i(TAG, "refresh");
    // If there is a key with developer provider name in the logins map, it
    // means the app user has used developer credentials
    if (!loginsMap.isEmpty()
            && loginsMap.containsKey(developerProvider)) {
        Log.i(TAG, "contains provider");
    } else {
        Log.i(TAG, "does not contain developer provider");
        Map<String, String> logins = new HashMap<>();
        logins.put(developerProvider, UserSingleton.imei);
        setLogins(logins);
    }

    // TODO:: Temp code to login. Once available, need to add code to GetToken from SocializeClient
    Login login = new Login();
    login.setImei(UserSingleton.imei);
    login.setPassword(UserSingleton.password);
    LoginReponse loginReponse = mSocializeClient.socializeAuthLoginPost(login);
    Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());

    update(loginReponse.getIdentityId(), loginReponse.getToken());

    Log.i(TAG, "updated");

    return loginReponse.getToken();
}

/*
 * (non-Javadoc)
 * @see com.amazonaws.auth.AWSBasicCognitoIdentityProvider#getIdentityId()
 */
/*
 * This method again has two flows as mentioned above depending on whether
 * the app user is using developer authentication or not. When using
 * developer authentication system, the identityId should be retrieved from
 * the developer backend. In the other case the identityId will be retrieved
 * using the getIdentityId() method which in turn calls Cognito GetId and
 * GetOpenIdToken APIs.
 */
@Override
public String getIdentityId() {
    Log.i(TAG, "getIdentityId");
    identityId = CognitoSyncClientManager.credentialsProvider.getCachedIdentityId();
    if (identityId == null) {
        Log.i(TAG, "identityId is null");
        if (!loginsMap.isEmpty()
                && loginsMap.containsKey(developerProvider)) {
            Log.i(TAG, "grabbing identityId using logins map");

            // TODO:: Temp code to login. Once available, need to add code to GetToken from SocializeClient
            Login login = new Login();
            login.setImei(loginsMap.get(developerProvider));
            login.setPassword(UserSingleton.password);
            LoginReponse loginReponse = mSocializeClient.socializeAuthLoginPost(login);
            Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());

            update(loginReponse.getIdentityId(), loginReponse.getToken());

            return loginReponse.getIdentityId();
        } else {
            return super.getIdentityId();
        }
    } else {
        return identityId;
    }
}

/*
 * (non-Javadoc)
 * @see
 * com.amazonaws.auth.AWSAbstractCognitoIdentityProvider#getProviderName()
 * Return the developer provider name which you chose while setting up the
 * identity pool in the Amazon Cognito Console
 */
@Override
public String getProviderName() {
    return developerProvider;
}

/**
 * This function validates the user credentials against the sample Cognito
 * developer authentication application. After that it stores the key and
 * token received from sample Cognito developer authentication application
 * for all further communication with the application.
 *
 * @param imei
 * @param password
 */
public void login(String imei, String password, Context context) {
    Log.i(TAG, "login");
    Login login = new Login();
    login.setImei(imei);
    login.setPassword(password);
    new AuthenticationTask(context).execute(login);
}

public void publishProfile(Context context, Profile profile){

    Log.i(TAG, "publishProfile");
    ProfileKey profileKey = new ProfileKey();
    profileKey.setUserID(identityId);
    profile.setKey(profileKey);

    new UploadProfileTask(context).execute(profile);
}

protected static SocializeClient getSocializeClientInstance() {
    if (mSocializeClient == null) {
        throw new IllegalStateException(
                "Dev Auth Client not initialized yet");
    }
    return mSocializeClient;
}

}

这是我的AuthenticationTask以及我尝试登录的地方,然后获取凭据以访问AWS数据库:

public class AuthenticationTask extends
    AsyncTask<Login, Void, Void> {

private static final String TAG = AuthenticationTask.class.getSimpleName();

// The user name or the developer user identifier you will pass to the
// Amazon Cognito in the GetOpenIdTokenForDeveloperIdentity API
private String mImei;
private String mPassword;

private GetCredentialsForIdentityResult credentialsForIdentityResult;

private boolean isSuccessful;

private final Context context;

public AuthenticationTask(Context context) {
    this.context = context;
}

@Override
protected Void doInBackground(Login... params) {
    Log.i(TAG, "doInBackground get refreshing threshold: " + CognitoCachingCredentialsProvider.DEFAULT_THRESHOLD_SECONDS);

    mImei = params[0].getImei();
    mPassword = params[0].getPassword();

    Login login = params[0];

    //        if(mPassword == null){
    //        Log.i(TAG, "register");
    //        mPassword = Utils.generateRandomString();
    //        final Register register = new Register();
    //        register.setImei(mImei);
    //        register.setPassword(mPassword);
    //        login.setPassword(mPassword);

    //        RegisterResponse registerResponse = AuthenticationProvider.getSocializeClientInstance().socializeAuthRegisterPost(register);
    //        Log.i(TAG, "registerResponse: " + registerResponse.getCreated());

    UserSingleton.password = mPassword;
    UserSingleton.getInstance().saveRegistrationInfo();
    Log.i(TAG, "imei: " + mImei);
    //        }

    Log.i(TAG, "calling login post");
    LoginReponse loginReponse = AuthenticationProvider.getSocializeClientInstance().socializeAuthLoginPost(login);
    Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());

    // Set up the loginsMap to send with the credentials request
    Map<String, String> loginsMap = new HashMap<>();
    loginsMap.put(CognitoSyncClientManager.developerIdentityProvider.getProviderName(), loginReponse.getToken());

    // get AWS credentials to access DB
    GetCredentialsForIdentityRequest credentialsForIdentityRequest = new GetCredentialsForIdentityRequest();
    credentialsForIdentityRequest.setIdentityId(loginReponse.getIdentityId());
    credentialsForIdentityRequest.setLogins(loginsMap);

    Log.i(TAG, "credentials request: " + credentialsForIdentityRequest.getIdentityId() + credentialsForIdentityRequest.getLogins());

    AmazonCognitoIdentityClient cognitoIdentityClient = new AmazonCognitoIdentityClient(CognitoSyncClientManager.credentialsProvider);
    credentialsForIdentityResult = cognitoIdentityClient
            .getCredentialsForIdentity(credentialsForIdentityRequest);

    isSuccessful = credentialsForIdentityResult != null;
    return null;
}

@Override
protected void onPostExecute(Void result) {
    if (isSuccessful) {
        Log.i(TAG, "accessKeyId: " + credentialsForIdentityResult.getCredentials().getAccessKeyId()
                + "\nsecretKey: " + credentialsForIdentityResult.getCredentials().getSecretKey()
                + "\nsessionToken: " + credentialsForIdentityResult.getCredentials().getSessionToken());

        CognitoSyncClientManager
                .addLogins(
                        ((AuthenticationProvider) CognitoSyncClientManager.credentialsProvider
                                .getIdentityProvider()).getProviderName(),
                        mImei);
    } else {
        Log.i(TAG, "login error: " + result);
    }
}

}

在我的刷新电话中,我只是在沉思。我不确定这是否正确。

现在最大的问题是在我尝试使用登录时启动,mSocializeClient.socializeAuthLoginPost(login)它似乎每次都会调用刷新,甚至在登录之前。刷新然后尝试再次登录并且它会不断地调用自己。< / p>

非常感谢任何帮助/解释。

1 个答案:

答案 0 :(得分:1)

dev auth示例的工作方式如下:

  1. DeveloperAuthenticationTask.login()应该登录服务器并获取会话密钥。
  2. 设置登录地图并调用DeveloperAuthenticationProvider.refresh()
  3. 刷新与服务器交换会话密钥以获取有效的认知令牌和身份ID,并使用令牌和身份ID调用更新。
  4. 在您的情况下,您没有此会话密钥,只有用户名和密码。所以你不需要AuthenticationTask。您所需要的只是:

    1. 您的AuthenticationProvider中的login(),它将用户名/密码放在安全的位置,设置登录地图并调用刷新(它实际上不应该尝试登录您的服务)。
    2. 在refresh()中,您从安全位置检索用户名/密码,调用您的服务,然后使用从您的服务返回的令牌和身份ID调用update。
    3. 您可以将代码简化为此流程吗?