最近のアクセス:
GAM のリモート認証を使用せずに SSO をエミュレートする方法

GAM では、GAMRemote 認証タイプ (ID プロバイダーを定義) を使用してシングル サイン オン (SSO) を実装します。しかし、GAM のリモート認証タイプを使用せずに、GAM で SSO をエミュレートする必要が生じる場合があります。
ここで取り上げるシナリオでは、さまざまな Web アプリケーションに (同じ会社の複数の支社で使用する) 多くのアプリケーションがインストールされています。同一の会社なので、ユーザーの定義は一度だけ行い、1 つの場所で管理します。また、ユーザーは、同じブラウザーで実行する限り、アプリケーションごとにログインするのではなく、一度ログインするだけですべてのアプリケーションにアクセスできることが求められます。この要件を満たすには、SSO が必要です。
また、同じユーザーがアプリケーションごとに異なるロールを持つ可能性があることも前提になります。GAM でのユーザーとロールの関係は、リポジトリに含まれています。ユーザーに対して (支社ごと、アプリケーションごとなど) 異なるロールをモデリングする場合の解決策の 1 つは、異なるリポジトリ (支社、アプリケーションなど) を作成することです。ここでは複数のリポジトリを作成し、アプリケーションに応じて、同じユーザーの複数のロールをグループ化します。
つまり、次のようなシナリオになります:
  1. いくつかのアプリケーション (それぞれ異なる Web アプリケーション内) が SSO を使用します。
  2. アプリケーションに応じて異なるロールを持つユーザーを一元管理します。
このシナリオは、「GAM を使用したアプリケーションのシングル サイン オン」を使用することで実現できます。ただし、これは GAM のリモート認証タイプを使用しない場合の代替手段です。

論理的根拠

解決策は次のようになります:
  1. n 個のリポジトリを持つ GAM データベースが 1 つのみで、リポジトリの名前空間はすべて同じです。この例では MyCompany という名前空間になります。
     
  2. 1 個のリポジトリをマスターリポジトリとして定義する必要があります。これが SSO をエミュレートし、アプリケーションはこのリポジトリに対して確認されます。Web アプリケーション内で GAMSession が生成され、マスターリポジトリに対して実行されます。また、これはクライアント上で生成されます (Web アプリケーションが複数あり、それぞれ異なるホストに置かれている可能性があるため)。このマスターリポジトリは ID プロバイダーのように機能します。

    マスターリポジトリには複数の目的があります:
  • ID プロバイダーとして機能し、ここで他のリポジトリへのすべての接続が一元管理され、検証されます。
  • ここで実行されている GAM バックエンドは、すべての新しいリポジトリの作成と管理に使用されます。
  • Web アプリケーションではすべての GAM 接続が connection.gam ファイルに定義されているため、管理ユーザーは任意の接続を使用して、他のユーザーを適切なリポジトリで有効にすることができます。
  • この解決策の一環として、アプリケーションにランディングページを追加し、エンドユーザーがアプリケーションや支社をリストから選択してアクセスできるようにすることも可能です。
       3.ログインは、マスターリポジトリに接続されているアプリケーションを実行する Web アプリケーション内で行われます。
       4.ユーザーはすべてのリポジトリで有効化される必要があります (ユーザーの名前空間がリポジトリの名前空間と同じである必要があります)。
: GAM リモートを使用する実際の ID プロバイダーでは、OAuth 2.0 プロトコルが使用されます。ここでは、OAuth 2.0 に厳密には従っていません。
それでも、パーティ間 (クライアントとマスター間) で次のものが一致しています:
  • アプリケーションの資格情報 (クライアント ID とクライアントシークレット)
  • コールバック URL
また、クライアントがリクエストを行った場所から応答が行われるように、ダイアログ内で状態が渡されます。
この解決策は次のように機能します。
  • ユーザーがアプリケーションを実行します。
  • クライアントアプリケーションがセッションを確認し、検証のためにマスターリポジトリ MyCompany にリダイレクトします。
  • マスターリポジトリは、任意のメカニズムを使用してユーザーを検証します (GAM 認証またはその他の外部プロシージャーを使用)。
  • セッションを取得すると、マスターリポジトリは呼び出し元アプリケーションにリダイレクトします。

解決策の実装

設定

この解決策の設定は次のようになります:
  1. マスターアプリケーションのナレッジベースの作成を開始します。GAM-Manager リポジトリに接続し、必要なすべてのリポジトリを作成します (アプリケーションごとに 1 個)。詳細は「GAM を使用して新しいリポジトリを作成する方法」を参照してください。
    各リポジトリ用に connection.gam ファイル内にエントリを追加することを忘れないでください。すべてのリポジトリで、リポジトリの名前空間が同じである必要があります。

    マスターリポジトリで次の処理を行います:
  • GAM Manager リポジトリへの接続を作成します。
  • GAM Manager に接続し、必要なすべてのリポジトリを作成します。
  • 各リポジトリ用の GAM 接続を作成し、connection.gam ファイルを更新します。
リポジトリ内でユーザーを作成すると、そのユーザーはそのリポジトリ内で自動的に有効化されます。また、リポジトリの名前空間が同じである限り、そのユーザーを他のリポジトリ内で有効化することもできます。「GAM リポジトリでのユーザーの有効化と無効化」を参照してください。すべてのリポジトリの管理者として同じ管理者ユーザーが割り当てられた場合、そのユーザーは、それらすべてのリポジトリの管理者として自動的に有効化されます。
      2.関連するリポジトリの GUID ([ Repository ID Environment ] プロパティ[ Administrator User Name ] プロパティ[ Administrator User Password ] プロパティ) を使用して、各アプリケーションのナレッジベースを設定します。[ Connection User Name ] プロパティ[ Connection User Password ] プロパティも設定します。この情報は、リポジトリの作成時に提供されたものです。

イメージ:38137.png
    3.アプリケーションごとに 1 個のナレッジベースがあるとして、それらすべてが同じ GAM データベースを参照するように設定します。

イメージ:38138.png

イメージ:38139.png
   4.次のリポジトリ接続を含めて、すべてのクライアントアプリケーション用に connection.gam ファイルを設定します:
  1. ローカルリポジトリへの接続
  2. マスターリポジトリへの接続
   5.マスターリポジトリ内で、各アプリケーション用に GAM アプリケーションを設定します。ランダムに生成されたクライアント ID およびクライアントシークレットを使用します。

イメージ:38134.png
   6.各アプリケーションの CallbackURL を設定する必要もあります。CallbackURL は、ログイン後にリダイレクトするための URL です。
入力するフィールドがないため、GAM OAV を使用してアプリケーションの定義を拡張し、フィールドを追加します。この場合、クライアントアプリケーション側からのリクエストを処理する HTTP プロシージャー (GenerateSessionFromIp) があります。
イメージ:38155.png
  7.マスターリポジトリで、ナレッジベースのすべてのアプリケーションを作成します。これらのアプリケーションからマスターリポジトリに接続するため、この処理を行わないと次のエラーが発生します:
アプリケーション GUID は確認されていません。アプリケーションの管理者にお問い合わせください。(GAM174)。

コーディング

両方の側 (マスター リポジトリ アプリケーションとクライアントアプリケーション) のコードを参照してください。

クライアントナレッジベース

アプリケーションの資格情報を取得し、マスターのログインにリダイレクトすることのみを目的とするオブジェクト (この例では SSOLogin) があります。
バージョンプロパティ GAM example login for web を SSOLogin に設定します。
SSOLogin オブジェクトの開始イベントは次のとおりです:
Event Start
   /* 最初の手順: システムパラメーターを取得 */
   /*マスターリポジトリの接続名を取得*/
   &ServerConnectionName = GetSysParameters.Udp(IdentityProviderParameters.ServerConnectionName)
   /* マスター webapp URL を取得 */
   &ServerURL = GetSysParameters.Udp(IdentityProviderParameters.ServerURL)
   /* セッションが無効なため実行に失敗した最後のオブジェクトを取得*/

    &RedirIP_SDT.AccessURL = GAMRepository.GetLastErrorsURL()

    /* セッション状態用にランダムな GUID を生成 */
    &GUID = GUID.NewGuid()
    &RedirIP_SDT.State = &GUID.ToString().Trim() 

    &WebSession.Set(IdentityProviderParameters.SessionData,  &RedirIP_SDT.ToJson())

    /* マスターリポジトリへの GAM 接続を確立 */
    &isOK = GAM.SetConnection(&ServerConnectionName, &Errors)
    If not &isOK
        Do 'DisplayMessages'
    else
       do "GetApplicationParameters"
       // IP にリダイレクト
        if not &ClientID.IsEmpty() and not &ClientSecret.IsEmpty() and not &CallbackURL.IsEmpty()
            &URL = format(!"%1?%2,%3,%4,%5",
            &ServerURL.Trim(),
            &RedirIP_SDT.State.Trim(),
            &ClientID.Trim(),
            &ClientSecret.Trim(),
            &CallbackURL.Trim())
            Link(&URL)
        endif
    EndIf
EndEvent

Sub "GetApplicationParameters"
    /* システムパラメーターからアプリケーション GUID を取得 */
    &AppGUID = GetSysParameters.Udp(IdentityProviderParameters.AppGUID)
    &GAMApplication = GAMApplication.GetByGUID(&AppGUID.Trim(), &GAMErrors)
    If &GAMErrors.Count > 0
        Do 'DisplayMessages'
    else
        &ClientID       = &GAMApplication.ClientId
        &ClientSecret   = &GAMApplication.ClientSecret
        /* マスターリポジトリで設定されている GAM アプリケーションの CallbackURL を取得 */
        GetApplicationCallBackURL(&id,&CallbackURL,&isOK)    
    EndIf
EndSub
このコードでは、GAMApplication の情報がマスターリポジトリ (接続が設定されている) から取得されます。
マスターリポジトリの接続名は connection.gam ファイルで確認できます:
イメージ:38117.png
システムパラメーターは次のとおりです (IPAppGUID: マスターリポジトリに登録されているアプリケーションの GUID、IPURL: serverURL、IPServerConnectionName):
イメージ:38154.png
GenerateSessionFromIP はクライアント上で実行されているプロシージャーで、コールバックプロシージャーです。このプロシージャーは受信リクエストを検証し、マスターリポジトリへの接続を生成します。また、GAMSession が有効な場合は、ローカルリポジトリに別の GAMSession を生成します。その後で、認証例外をスローしたオブジェクトにリダイレクトします。
&isOk = GAM.SetConnection(&ServerConnectionName, &Errors)
&isSessionOK = GAMRepository.ValidAccessToken(&token, &GAMSession, &GAMErrors)
If &isSessionOK  AND  not &GAMSession.IsAnonymous

/*システムパラメーターからローカル接続名を取得 */
&ClientAppName = GetSysParameters.Udp(IdentityProviderParameters.ClientConnectionName)

/*ローカル接続を設定*/
&isOk = GAM.SetConnection(&ClientAppName, &Errors)
// 正しいオブジェクトにリダイレクト
入力値の説明:
IdentityProviderParameters.ClientConnectionName
      クライアント側の接続名を参照します。

マスターリポジトリ

このナレッジベースではログインオブジェクトです。基本的には、開始イベントでこのオブジェクトがマスターリポジトリへの接続を設定し、リクエストパラメーターを検証し、callbackURL をロードします。
Event Start
&isOK = GAM.SetConnection(!"MasterRepository", &Errors)
If not &State.IsEmpty() AND not &ClientID.IsEmpty() AND not &ClientSecret.IsEmpty() AND not &CallbackURL.IsEmpty()
        // 基本パラメーターを検証
GetApplicationbyClientId(&ClientID,&ClientSecret,&GAMGUID,&GAMAppCallbackURL)
&GAMApplication = GAMApplication.GetByGUID(&GAMGUID, &GAMErrors)
If &GAMApplication.ClientId = &ClientID AND &GAMApplication.ClientSecret = &ClientSecret and &CallbackURL = &GAMAppCallbackURL
      &AppOK = True
      // データを保存
      &ClientData_SDT.CallbackURL = &CallbackURL
      &ClientData_SDT.State       =  &State
      &WebSession.Set(!"ClientData",  &ClientData_SDT.ToJson())
 Else
         &AppOK = False
 Endif
EndEvent    
Refresh イベントで、GAMSession が有効な場合は、オブジェクトにリダイレクトします。
Event Refresh
    &Errors = GAMRepository.GetLastErrors()
    If &Errors.Count > 0
       // エラーを表示
    else
        If &AppOK
            &SessionValid = GAMSession.IsValid(&GAMSession, &Errors)
            If &SessionValid  AND  not &GAMSession.IsAnonymous
                &WebSession.Set(!"ClientData",  &ClientData_SDT.ToJson())
                //クライアントにリダイレクト
                &link = format(!"%1?%2,%3", &ClientData_SDT.CallbackURL, &ClientData_SDT.State, &GAMSession.Token)   
                Link(&link)
            else
             //
            EndIf
        else
         //
        EndIf
    EndIf
EndEvent
ログインイベントもあります:
Event Enter
    &LoginOK = GAMRepository.Login(&UserName, &UserPassword, &AdditionalParameter, &Errors )
    If &LoginOK
        msg(format(!"Login succedded. %1", now()))
        refresh
    else
        msg(format(!"Login result: %1", &LoginOK))    
        Do 'DisplayMessages'
    EndIf
EndEvent
マスター ナレッジ ベースはこちらから、クライアント ナレッジ ベースはこちらからダウンロードしてください。

使用可能バージョン

GeneXus 15 Upgrade 9 以降。

考慮事項

Deploy Tool ユーティリティを使用してリポジトリ間のデータ移行を行う場合は、管理者ロールのエクスポートとインポートが必要です。この情報は、リポジトリを変更するときに必要になります。

解決策のトラブルシューティング

エラーが発生した場合は「GAM のトレースを生成する方法」を参照してください。
.NET の場合は ASP.NET トレースをアクティベートすると便利です。

考えられるエラー

1.GAM 接続が指定されていない

エラーの詳細は次のとおりです:
GAM への接続が指定されていません。アプリケーションの管理者にお問い合わせください。(GAM1)
トレースを見ると、コードに追加されたデバッグメッセージと GAM のトレース デバッグ メッセージを確認できます:
イメージ:38164.png
このエラーが発生した場合は、確立しようとしている接続がリポジトリで正しく定義されていること、および該当するエントリが connection.gam ファイル内に存在することを確認してください。

2.アプリケーション GUID が確認されていない

このエラーは、application.gam ファイルで指定されているアプリケーションが、接続しようとしているリポジトリ内に存在しないために発生します。エラーの詳細は次のとおりです:
アプリケーション GUID RepId:2 - AppGUID:789c15aa-b18b-4a3e-9e21-7a8e5cd2aba5 は確認されていません。アプリケーションの管理者にお問い合わせください。(GAM174)
マスターリポジトリに接続しているときにこのエラーが発生した場合は、すべてのアプリケーションがリポジトリ内で定義されていることを確認してください。
gamexamplelogin を通常どおりに実行する (マスターリポジトリを経由せずにローカルリポジトリに接続する) 必要がある場合は、gamexamplelogin が connection.gam ファイル内の最初の接続に対して setconnection を実行するかどうかを確認してください。この接続がマスターの場合、ローカルアプリケーションがそこに存在しない可能性があります。
gamexamplelogin オブジェクトは、接続を試みているリポジトリを示します。
イメージ:38142.png

3.GAM エラーが見つからない

エラーの詳細は次のとおりです:
GAM Error Not found.(GAM200)
このエラーは、無効なアプリケーション GUID を使用して次の行を実行しようとした場合にスローされることがあります:
&GAMApplication = GAMApplication.GetByGUID(&AppGUID, &GAMErrors)

4.アプリケーションのループまたは過剰なリダイレクトの詳細

アプリケーションがループする場合です (トレースに、ログインがマスターリポジトリでは成功したが、クライアントでは成功しなかったことが示されます):
イメージ:38156.png
クライアント上で connection.gam の設定を間違っていないか確認してください。トレースで次を確認できます:
イメージ:38157.png

5.アプリケーション GUID RepId - AppGUID が確認されていない

リポジトリの変更中に次のエラーが表示されます:
アプリケーション GUID RepId:X - AppGUID:Y は確認されていません。アプリケーションの管理者にお問い合わせください。(GAM174)
メインのリポジトリと関連するクライアントリポジトリで appGUID の値が同じであることを確認してください。これが要件になります。解決する方法の 1 つは、アプリケーションを重複させ、クライアントの方に正しい AppGUID を割り当てることです。

6.ユーザーが見つからない

ログイン時に次のエラーが表示されます:
ユーザーが見つかりません。(GAM7)
そのユーザーがローカルリポジトリとコアに作成されていることを確認してください。両方のリポジトリでユーザーが有効化されている必要があります。

Created: 19/03/25 17:59 by Admin Last update: 24/03/25 23:57 by Admin
カテゴリ
Powered by GXwiki 3.0