Android中使用Google提供程序SDK的Microsoft Azure Mobile身份验证

时间:2016-07-24 03:12:06

标签: android azure authentication

我目前正在使用原生Android应用和后端的C#测试Microsoft Azure和应用服务/移动应用功能。

我开始使用入门应用程序(ToDo)作为基础应用程序,现在我尝试使用https://azure.microsoft.com/en-us/documentation/articles/app-service-authentication-overview/页面和Google作为提供程序启用身份验证。

到目前为止我已经

  • 使用OAuth Web客户端创建了一个Google项目
  • 授权重定向uri设置为:https://.azurewebsites.net/.auth/login/google/callback
  • 在Azure门户和App Service实例中,我已启用授权/身份验证
  • "请求未经过身份验证时要执行的操作"选项设置为"允许请求"
  • 对于Google提供商,我设置了客户端ID和客户端密钥

在Android应用中,我使用GoogleApiClient类让用户选择Google帐户。我也获得了ID令牌和服务器验证码

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(R.string.server_client_id))
            .requestServerAuthCode(getString(R.string.server_client_id))
            .build();
    mScopes = gso.getScopeArray();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

用户拿起帐户后,我会检索令牌和代码,然后使用GoogleAuthUtil类请求访问令牌。在我获得access_token之后,我尝试将其与App Service令牌(authenticate2方法)交换

private void handleSignInResult(GoogleSignInResult result) {
    Log.d("", "handleSignInResult: " + result.isSuccess());

    if(result.isSuccess()) {
        final GoogleSignInAccount account = result.getSignInAccount();

        final String idToken = account.getIdToken();
        String serverAuthCode = account.getServerAuthCode();

        mSignInButton.setVisibility(View.GONE);
        mGoogleUserText.setText(account.getDisplayName());
        mGoogleUserText.setVisibility(View.VISIBLE);

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.edit().putString("idToken", idToken).commit();
        prefs.edit().putString("serverAuthCode", serverAuthCode).commit();

        new AsyncTask<Void, Void, String>() {

            @Override
            protected String doInBackground(Void... params) {
                try {

                    StringBuilder scopesBuilder = new StringBuilder("oauth2:");
                    for(Scope scope : mScopes) {
                        scopesBuilder//.append("https://www.googleapis.com/auth/")
                                .append(scope.toString())
                                .append(" ");
                    }

                    String token = GoogleAuthUtil.getToken(ToDoActivity.this,
                            account.getEmail(), scopesBuilder.toString());

                    return token;
                } catch (IOException | GoogleAuthException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(String result) {
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ToDoActivity.this);
                prefs.edit().putString("accessToken", result).apply();

                authenticate2();
            }
        }.execute();
    } else {
        mSignInButton.setVisibility(View.VISIBLE);
        mGoogleUserText.setVisibility(View.GONE);
    }
}

private void authenticate2() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

    String idToken = prefs.getString("idToken", null);
    String serverAuthCode = prefs.getString("serverAuthCode", null);
    String accessToken = prefs.getString("accessToken", null);

    JsonObject json = new JsonObject();
    json.addProperty("access_token", accessToken);
    json.addProperty("id_token", idToken);
    json.addProperty("authorization_code", serverAuthCode);

    ListenableFuture<MobileServiceUser> loginFuture =
            mClient.login(MobileServiceAuthenticationProvider.Google, json);

    Futures.addCallback(loginFuture, new FutureCallback<MobileServiceUser>() {
        @Override
        public void onSuccess(MobileServiceUser result) {
            createTable();
        }

        @Override
        public void onFailure(Throwable t) {
            Log.e(TAG, t.getMessage(), t);
        }
    });
}

所以我使用MobileServiceClient.login()方法将用户的access_token发送回服务器,以便返回Azure会话。

然而,这个调用失败了,我得到了一个MobileServiceException:

com.microsoft.windowsazure.mobileservices.MobileServiceException:您无权查看此目录或页面。

任何想法我在这里缺少什么?

由于

1 个答案:

答案 0 :(得分:0)

这不仅仅是尴尬: - )

我首先尝试使用Google tokeninfo端点“手动”验证id_token: https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=

但是我收到了一个没有提供大量信息的一般性错误。

然后我使用Google API Java客户端库并创建了一个小测试来验证我的令牌(此处有更多信息:https://developers.google.com/identity/sign-in/android/backend-auth

那个测试也失败了,我意识到原因是我的令牌的到期时间比当前时间短。而这种情况正在发生,因为我的模拟器时间不正确!

当我设置“正确”时区时,一切都按预期工作。

对不起帖子的人。您可以在此处使用代码作为模板,不要忘记检查您的模拟器时间: - )