2017-02-01 8 views
0

MVC Web、IOS、Androidの3つのクライアントがあります。アイデンティティサーバ3をプロジェクトのIdPとして設定しました。 ハイブリッドフローを使用して、すべてがMVCアプリケーションに適しています。AppAuth oidc IDサーバの認証に無効な状態エラーが発生しました

(IOSとAndroid用)ネイティブoidcクライアント(AppAuth IOSAppAuth android)を使用すると、フローをHybrid with PKCEとして設定しても機能しません。

Xamarinを使用してアンドロイド上でPOCを作成しようとすると、IdentityModel.oidcClientを使用してすべてが期待どおりに動作し、アクセス権、リフレッシュIDおよびIDトークンが取得されます。 私は、次のエラーを取得していますIOSのためのAppAuthとAndroidを使用して:

{"type":0,"code":9,"errorDescription":"Response state param did not match request state"} 

欠けているものを任意のアイデアを?

私は、これらの2つのネイティブクライアントがクライアントの共有秘密を要求していないと考えているので、そのためにフローが壊れています。

+0

を確認することができ、このoidcライブラリは、クエリ文字列などを期待している間に許可応答は、リダイレクトURIにフラグメントとして返されるためでありますその応答では、図書館は応答を得ることに成功していません。 ライブラリは仕様に従っていませんが、実際にはどちらのライブラリもハイブリッドフローをサポートしているとは疑いがあります。 それらのライブラリはGoogleのIdPのケースを処理しており、それは実装者のためのものです。 –

+0

ライブラリはGoogle固有のものではありません。彼らはネイティブアプリケーション用のOAuth2の推奨事項を実装しています:https://tools.ietf.org/html/draft-ietf-oauth-native-apps-07 – iainmcgin

答えて

0

私たちは、AppAuth-Android hereでのハイブリッドフローのサポートについて未解決の問題があります。これの主な問題は、アクセストークンが期限切れになるたびにSafariViewController/CustomTab経由でウェブフローを繰り返しトリガする必要があるため、ハイブリッドフローがモバイルアプリケーションに適していないことです。リフレッシュトークンを取得して、アクセストークンのバックグラウンド更新を許可することは、ネイティブアプリにとってはより良い方法です。

IdentityServer3は認定OpenID Connectの実装であるため、認証コードフローを使用してリフレッシュトークンを取得できる必要があります。

new Client 
     { 
      ClientId = "myClientId", 
      ClientName = "myClientName", 
      AllowedGrantTypes = GrantTypes.CodeAndClientCredentials, 
      RequireConsent = false, 

      ClientSecrets = 
      { 
       new Secret("myClientSecret".Sha256()) 
      }, 

      RedirectUris = { "myRedirectUri://callback" }, 

      AllowedScopes = 
      { 
       IdentityServerConstants.StandardScopes.OpenId, 
       IdentityServerConstants.StandardScopes.Profile, 
       IdentityServerConstants.StandardScopes.Email, 
       IdentityServerConstants.StandardScopes.Phone, 
      }, 

      AllowOfflineAccess = true 
     } 

クリックログインのAndroidで:

AuthManager authManager = AuthManager.getInstance(this); 
    AuthorizationService authService = authManager.getAuthService(); 
    Auth auth = authManager.getAuth(); 

    AuthorizationRequest authRequest = new AuthorizationRequest 
     .Builder(
     authManager.getAuthConfig(), 
     auth.getClientId(), 
     auth.getResponseType(), 
     Uri.parse(auth.getRedirectUri())) 
     .setScope(auth.getScope()) 
     .build(); 

    Intent authIntent = new Intent(this, LoginAuthActivity.class); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, authRequest.hashCode(), authIntent, 0); 

    authService.performAuthorizationRequest(
     authRequest, 
     pendingIntent); 

を求める

-1

データは、サーバー上の

、モバイルアプリ内とアイデンティティサーバーで同じである必要がありますトークン:

final AuthorizationResponse resp = AuthorizationResponse.fromIntent(getIntent()); 
    AuthorizationException ex = AuthorizationException.fromIntent(getIntent()); 

    final AuthManager authManager = AuthManager.getInstance(this); 
    authManager.setAuthState(resp,ex); 

    if (resp != null) { 

     ClientSecretPost clientSecretPost = new ClientSecretPost(authManager.getAuth().getClientSecret()); 
     TokenRequest tokenRequest = new TokenRequest 
      .Builder(authManager.getAuthConfig(), authManager.getAuth().getClientId()) 
      .setAuthorizationCode(resp.authorizationCode) 
      .setRedirectUri(Uri.parse(authManager.getAuth().getRedirectUri())) 
      .build(); 

     mAuthService = authManager.getAuthService(); 

     mAuthService.performTokenRequest(tokenRequest, clientSecretPost, new AuthorizationService.TokenResponseCallback() { 
      @Override public void onTokenRequestCompleted(@Nullable TokenResponse response, @Nullable AuthorizationException ex) { 
       if(ex == null) { 
        authManager.updateAuthState(response,ex); 
        MyApp.Token = authManager.getAuthState().getIdToken(); 
        startService(new Intent(LoginAuthActivity.this, TokenService.class)); 
        Intent mainIntent = new Intent(LoginAuthActivity.this, MainActivity.class); 
        startActivity(mainIntent); 
        finish(); 
       } 
       else{ 
        Intent loginIntent = new Intent(LoginAuthActivity.this, LoginActivity.class); 
        startActivity(loginIntent); 
        finish(); 
       } 
      } 
     }); 

     // authorization completed 
    } else { 
     // authorization failed, check ex for more details 
     Intent loginIntent = new Intent(LoginAuthActivity.this, LoginActivity.class); 
     startActivity(loginIntent); 
     finish(); 
    } 

認証マネージャークラス:

public class AuthManager { 
private static AuthManager instance; 
private AuthState mAuthState; 
private Auth mAuth; 
private AuthorizationServiceConfiguration mAuthConfig; 
private SharedPreferencesRepository mSharedPrefRep; 
private AuthorizationService mAuthService; 

public static AuthManager getInstance(Context context) { 
    if (instance == null) { 
     instance = new AuthManager(context); 
    } 
    return instance; 
} 

private AuthManager(Context context){ 
    mSharedPrefRep = new SharedPreferencesRepository(context); 
    setAuthData(); 
    mAuthConfig = new AuthorizationServiceConfiguration(
      Uri.parse(mAuth.getAuthorizationEndpointUri()), 
      Uri.parse(mAuth.getTokenEndpointUri()), 
      null); 
    mAuthState = mSharedPrefRep.getAuthState(); 

    mAuthService = new AuthorizationService(context); 
} 



public AuthorizationServiceConfiguration getAuthConfig() { 
    return mAuthConfig; 
} 

public Auth getAuth() { 
    if(mAuth == null){ 
     setAuthData(); 
    } 

    return mAuth; 
} 

public AuthState getAuthState(){ 
    return mAuthState; 
} 

public void updateAuthState(TokenResponse response, AuthorizationException ex){ 
    mAuthState.update(response,ex); 
    mSharedPrefRep.saveAuthState(mAuthState); 
} 

public void setAuthState(AuthorizationResponse response, AuthorizationException ex){ 
    if(mAuthState == null) 
     mAuthState = new AuthState(response,ex); 

    mSharedPrefRep.saveAuthState(mAuthState); 
} 

public AuthorizationService getAuthService(){ 
    return mAuthService; 
} 

private void setAuthData(){ 
    mAuth = new Auth(); 
    mAuth.setClientId(BuildConfig.CLIENT_ID); 
    mAuth.setAuthorizationEndpointUri(BuildConfig.AUTHORIZSTION_END_POINT_URI); 
    mAuth.setClientSecret(BuildConfig.CLIENT_SECRET); 
    mAuth.setRedirectUri(BuildConfig.REDIRECT_URI); 
    mAuth.setScope(BuildConfig.SCOPE); 
    mAuth.setTokenEndpointUri(BuildConfig.TOKEN_END_POINT_URI); 
    mAuth.setResponseType(BuildConfig.RESPONSE_TYPE); 
} 
} 

ここでサービスは、リフレッシュトークンを要求します。

私はAppAuth-のAndroidでのIdentity Server 4を使用してサンプルを作っている、あなたはそれをhere

+1

このリンクは質問に答えるかもしれませんが、必須の部分ここでの回答と参照用のリンクを提供します。リンクされたページが変更された場合、リンクのみの回答は無効になります。 - [レビューから](/レビュー/低品質投稿/ 16649743) – Alberto

+0

I回答を編集 – Hadi

関連する問題