クライアント定義を作成するユーザとサーバを設定するユーザは異なる可能性が高いためです。また、クライアント定義の継続的な作成が必要になる場合があるためです。そのため、クライアント定義の作成タスクは、独立したセクションとしてこの記事の最後に収録しています。
InterSystems IRIS 承認サーバのカスタム・メソッドの実装
承認サーバの動作をカスタマイズするには、"コードのカスタマイズ・オプション" の説明に従ってクラスを定義します。次に、このセクションの情報に基づいて、カスタマイズする処理手順に応じて、これらのクラスのメソッドを定義します。
-
認証前のオプションのカスタム処理
-
ユーザの識別
-
ユーザの検証とクレームの指定
-
必要に応じたユーザへの許可の表示
-
認証後のオプションのカスタム処理
-
アクセス・トークンの生成
これらのサブセクションに続く最後のサブセクションでは、このサーバがクライアント資格情報付与タイプをサポートする必要がある場合にクライアントを検証する方法について説明します。クライアント資格情報付与タイプでは、前述のリストの手順 2 ~ 4 は使用しません。
認証前のオプションのカスタム処理
ここに記載されている情報は、すべての付与タイプに当てはまります。
ユーザを認証する前にカスタム処理を実行するには、認証クラスの BeforeAuthenticate() メソッドを実装します。このメソッドには、以下のシグニチャがあります。
ClassMethod BeforeAuthenticate(scope As %ArrayOfDataTypes,
properties As %OAuth2.Server.Properties) As %Status
以下はその説明です。
必要に応じて、メソッドのこれらの引数のいずれかまたは両方を変更します。どちらの引数もユーザの識別に使用されるメソッドに後で渡されます。このメソッドは %StatusOpens in a new tab を返す必要があります。
通常、このメソッドを実装する必要はありません。ただし、このメソッドの使用事例の1つとして、FHIR® で使用される launch と launch/patient のスコープを実装するのに利用するというようなものがあります。この事例では、特定の患者を含めるようにスコープを調整する必要があります。
ユーザの識別
ここに記載されている情報は、承認コード付与タイプと暗黙付与タイプにのみ当てはまります。
ユーザを識別するには、認証クラスの DisplayLogin() メソッドを実装します。DisplayLogin() メソッドには、以下のシグニチャがあります。
ClassMethod DisplayLogin(authorizationCode As %String,
scope As %ArrayOfDataTypes,
properties As %OAuth2.Server.Properties,
loginCount As %Integer = 1) As %Status
以下はその説明です。
このメソッドは、ユーザのログイン・フォームを表示する HTML を記述します。ログイン・フォームには、[ユーザ名] フィールド、[パスワード] フィールド、[承認コード] フィールド (非表示) を含める必要があります。既定の DisplayLogin() メソッドは、%CSP.PageOpens in a new tab の InsertHiddenField() メソッドを使用して、承認コードの非表示フィールドを追加します。
通常、このフォームには Login ボタンと Cancel のボタンがあります。これらのボタンによってフォームが送信されます。ユーザが Login ボタンでフォームを送信すると、このメソッドはユーザ名とパスワードを受け入れます。ユーザが Cancel ボタンでフォームを送信すると、承認プロセスは access_denied のエラーを返して終了します。
実装時に、同じページに許可を表示することも選択できます。その場合、メソッドはスコープを表示し、Accept という名前のボタンを使用してページを送信します。
このメソッドは %StatusOpens in a new tab を返す必要があります。
properties.CustomProperties の更新
フォームに名前が p_ で始まる要素が含まれている場合は、その要素に特別な処理を施します。InterSystems IRIS は DisplayLogin() メソッドが返した要素の値を properties.CustomProperties 配列に追加するとき、最初に p_ 接頭語を名前から削除します。例えば、フォームに p_addme という名前の要素が含まれている場合、InterSystems IRIS は addme (および p_addme 要素の値) を properties.CustomProperties 配列に追加します。
必要に応じて properties の他のプロパティをメソッドで直接設定することもできます。
ユーザの検証とクレームの指定
ここに記載されている情報は、クライアント資格情報付与タイプを除くすべての付与タイプに当てはまります。(この付与タイプについては、"クライアントの検証" を参照してください。)
ユーザを検証し、トークン・エンドポイント、Userinfo エンドポイント、トークン・イントロスペクション・エンドポイントによって返されるクレームを指定するには、ユーザ検証クラスの ValidateUser() メソッドを定義します。このメソッドには、以下のシグニチャがあります。
ClassMethod ValidateUser(username As %String,
password As %String,
scope As %ArrayOfDataTypes,
properties As %OAuth2.Server.Properties,
Output sc As %Status) As %Boolean
以下はその説明です。
このメソッドは、以下を実行します。
-
パスワードが指定されたユーザ名に対応していることを確認します。
-
業務のニーズに応じて scope および properties 引数を適宜使用します。
-
必要に応じて properties オブジェクトを変更してクレーム値を指定するか、新しいクレームを追加します。以下に例を示します。
// Setup claims for profile and email OpenID Connect scopes.
Do properties.SetClaimValue("sub",username)
Do properties.SetClaimValue("preferred_username",username)
Do properties.SetClaimValue("email",email)
Do properties.SetClaimValue("email_verified",0,"boolean")
Do properties.SetClaimValue("name",fullname)
-
エラーの場合には sc 変数を設定します。
-
ユーザを有効と見なす場合は 1 を返し、それ以外の場合は 0 を返します。
ValidateUser() が値を返すと、承認サーバは properties オブジェクトの以下の値を自動的に設定します (これらの値が欠落している場合)。
許可の表示
ここに記載されている情報は、承認コード付与タイプと暗黙付与タイプにのみ当てはまります。
ユーザの検証後に許可を表示するには、認証クラスの DisplayPermissions() メソッドを実装します。このメソッドには、以下のシグニチャがあります。
ClassMethod DisplayPermissions(authorizationCode As %String,
scopeArray As %ArrayOfDataTypes,
currentScopeArray As %ArrayOfDataTypes,
properties As %OAuth2.Server.Properties) As %Status
以下はその説明です。
このフォームには Accept ボタンと Cancel のボタンが必要です。これらのボタンによってフォームが送信されます。ユーザが Accept ボタンでフォームを送信すると、このメソッドは承認を続行します。ユーザが Cancel ボタンでフォームを送信すると、承認プロセスは終了します。
認証後のオプションのカスタム処理
ここに記載されている情報は、すべての付与タイプに当てはまります。
認証後にカスタム処理を実行するには、認証クラスの AfterAuthenticate() メソッドを実装します。このメソッドには、以下のシグニチャがあります。
ClassMethod AfterAuthenticate(scope As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties) As %Status
以下はその説明です。
必要に応じて、メソッドのこれらの引数のいずれかまたは両方を変更します。具体的には、プロパティを認証 HTTP 応答に追加することもできます。その場合は、プロパティを properties.ResponseProperties に追加します。
通常、このメソッドを実装する必要はありません。ただし、このメソッドの使用事例の1つとして、FHIR® で使用される launch と launch/patient のスコープを実装するのに利用するというようなものがあります。この事例では、特定の患者を含めるようにスコープを調整する必要があります。
アクセス・トークンの生成
ここに記載されている情報は、すべての付与タイプに当てはまります。
アクセス・トークンを生成するには、トークン生成クラスの GenerateAccessToken() メソッドを実装します。このメソッドには、以下のシグニチャがあります。
ClassMethod GenerateAccessToken(properties As %OAuth2.Server.Properties, Output sc As %Status) As %String
以下はその説明です。
このメソッドはアクセス・トークンを返します。このアクセス・トークンは properties 引数に基づきます。このメソッドで、クレームを JSON 応答オブジェクトに追加することもできます。そのためには、properties オブジェクトの ResponseProperties 配列プロパティを設定します。
クライアントの検証
ここに記載されている情報は、クライアント資格情報付与タイプにのみ当てはまります。
クライアント資格情報を検証し、トークン・エンドポイント、Userinfo エンドポイント、トークン・イントロスペクション・エンドポイントによって返されるクレームを指定するには、ユーザ検証クラスの ValidateClient() メソッドを定義します。このメソッドには、以下のシグニチャがあります。
ClassMethod ValidateClient(clientId As %String,
clientSecret As %String,
scope As %ArrayOfDataTypes,
Output properties As %OAuth2.Server.Properties,
Output sc As %Status) As %Boolean
以下はその説明です。
このメソッドは、以下を実行します。
-
クライアント秘密鍵が指定されたクライアント ID に対応していることを確認します。
-
業務のニーズに応じて scope および properties 引数を適宜使用します。
-
必要に応じて、properties オブジェクトを変更してクレーム値を指定します。以下に例を示します。
// Setup claims for profile and email OpenID Connect scopes.
Do properties.SetClaimValue("sub",username)
Do properties.SetClaimValue("preferred_username",username)
Do properties.SetClaimValue("email",email)
Do properties.SetClaimValue("email_verified",0,"boolean")
Do properties.SetClaimValue("name",fullname)
-
エラーの場合には sc 変数を設定します。
-
ユーザを有効と見なす場合は 1 を返し、それ以外の場合は 0 を返します。
ValidateClient() が値を返すと、承認サーバは properties オブジェクトの以下の値を自動的に設定します (これらの値が欠落している場合)。
%OAuth2.Server.Properties オブジェクトの詳細
前のセクションで説明したメソッドでは、properties 引数を使用していますが、この引数は%OAuth2.Server.PropertiesOpens in a new tab のインスタンスです。%OAuth2.Server.PropertiesOpens in a new tab クラスの目的は、承認サーバ・コード内のメソッド間で受け渡す必要がある情報を保持することです。このセクションでは、このクラスの基本プロパティとクレーム関連のプロパティについて説明します。このクラスには、クレームを操作するメソッドもあります。これらのメソッドについては、最後のサブセクションで説明します。
基本プロパティ
%OAuth2.Server.PropertiesOpens in a new tab クラスには以下の基本プロパティがあります。これらのプロパティは、カスタム・コードの内部処理の情報の伝達に使用されます。
RequestProperties
Property RequestProperties as array of %String (MAXLEN="");
承認要求のクエリ・パラメータが含まれています。
このプロパティは配列であるため、通常の配列インタフェースを使用して操作します。(これは、このクラスの他のプロパティでも同様です。)例えば、クエリ・パラメータの値を取得するには、RequestProperties.GetAt(parmname) を使用します。ここで、parmname はクエリ・パラメータの名前です。
ResponseProperties
Property ResponseProperties as array of %String (MAXLEN="");
トークン要求への JSON 応答オブジェクトに追加されるプロパティがすべて含まれます。このプロパティは必要に応じて設定します。
ServerProperties
Property ServerProperties as array of %String (MAXLEN="");
承認サーバがカスタマイズ・コードと共有するプロパティが含まれます。認証クラスで使用するために、クライアント・プロパティの logo_uri、client_uri、policy_uri、tos_uri がこの方法で共有されます。
クレーム関連のプロパティ
%OAuth2.Server.PropertiesOpens in a new tab クラスには、IntrospectionClaims、IDTokenClaims、UserinfoClaims、JWTClaims プロパティがあります。これらのプロパティは、必須のクレーム、特にカスタム・クレームに関する情報を伝達します。
このクラスには、実際のクレーム値を伝達する ClaimValues プロパティもあります。カスタマイズ・コードでクレームの値を設定する必要があります (通常は ValidateUser クラス内で)。
以下のリストで、これらのプロパティについて説明します。
IntrospectionClaims
Property IntrospectionClaims as array of %OAuth2.Server.Claim;
イントロスペクション・エンドポイントが返すクレームを指定します (必須クレームの基本セットの範囲を超えて指定)。承認サーバは scope、client_id、username、token_type、exp、iat、nbf、sub、aud、iss、jti クレームを (このプロパティに含まれていない場合でも) 返します。
ほとんどの場合、このプロパティの値には空の文字列を使用できます。このプロパティは、claims 要求パラメータをサポートするために指定されます (詳細は、OpenID Connect CoreOpens in a new tab のセクション 5.5 を参照してください)。
形式的にはこのプロパティは配列であり、その配列キーは (ClaimValues プロパティの名前と一致する) クレーム名であり、その配列値は %OAuth2.Server.ClaimOpens in a new tab のインスタンスです。%OAuth2.Server.ClaimOpens in a new tab クラスには以下のプロパティがあります。
通常、クレームの値は ValidateUser クラスで設定されます。
IDTokenClaims
Property IDTokenClaims as array of %OAuth2.Server.Claim;
承認サーバが IDToken で必要とするクレームを指定します (必須クレームの基本セットの範囲を超えて指定)。承認サーバは、iss、sub、exp、aud、azp クレームを (このプロパティに含まれていない場合でも) 必要とします。
このプロパティはオブジェクトの配列です。詳細は、IntrospectionClaims プロパティの項目を参照してください。
ほとんどの場合、このプロパティの値には空の文字列を使用できます。このプロパティは、claims 要求パラメータをサポートするために指定されます (詳細は、OpenID Connect CoreOpens in a new tab のセクション 5.5 を参照してください)。
UserinfoClaims
Property UserinfoClaims as array of %OAuth2.Server.Claim;
Userinfo エンドポイントが返すクレームを指定します (必須クレームの基本セットの範囲を超えて指定)。承認サーバは sub クレームを (このプロパティに含まれていない場合でも) 返します。
ほとんどの場合、このプロパティの値には空の文字列を使用できます。このプロパティは、OpenID Connect Core のセクション 5.5 をサポートするために提供されます。
このプロパティはオブジェクトの配列です。詳細は、IntrospectionClaims プロパティの項目を参照してください。
クレームは、スコープと要求のクレーム・パラメータに基づいて定義されます。クレームの戻り値は、ClaimValues プロパティの同じキーを持ちます。通常、クレームの値は ValidateUser クラスで設定されます。
JWTClaims
Property JWTClaims as array of %OAuth2.Server.Claim;
JWT ベースの既定のアクセス・トークン・クラス (%OAuth2.Server.JWTOpens in a new tab) が返す JWT アクセス・トークンで必要とされるクレームを必須クレームの基本セットの範囲を超えて指定します。承認サーバは、iss、sub、exp、aud、jti クレームを (このプロパティに含まれていない場合でも) 返します。
このプロパティはオブジェクトの配列です。詳細は、IntrospectionClaims プロパティの項目を参照してください。
このクレームはカスタマイズ・コードによって定義されます。通常、クレームの値は ValidateUser クラスで設定されます。
ClaimValues
property ClaimValues as array of %String(MAXLEN=1024);
実際のクレーム値とその型を指定します。このプロパティを操作するには、次のセクションのメソッドを使用します。
このプロパティを直接操作する必要がある場合は、このプロパティが以下の特徴を持つ配列であることに注意してください。
-
配列キーはクレーム名です。
-
配列値は $LISTBUILD(type,value) の形式をとります。ここで、type は値のタイプを保持し、value は実際の値を保持します。type には "string"、"boolean"、"number"、または "object" を指定できます。 type が "object" の場合、value は文字列としてシリアル化された JSON オブジェクトとなります。
value は $LIST 構造となります。この場合、クレーム値はシリアル化されるときに JSON 配列としてシリアル化され、それぞれの配列項目は指定された type となります。
クレームを操作するメソッド
%OAuth2.Server.PropertiesOpens in a new tab クラスは、ClaimValues プロパティの操作を簡素化するために使用できるインスタンス・メソッドも提供します。
SetClaimValue()
Method SetClaimValue(name As %String, value As %String, type As %String = "string")
name 引数で指定したクレームの値を設定することで、ClaimValues プロパティを更新します。type 引数はクレームの型を示します。型には "string" (既定値)、"boolean"、"number"、"object" があります。 type が "object" の場合、value は文字列としてシリアル化された JSON オブジェクトでなければなりません。
value は $LIST 構造にすることもできます。この場合、クレーム値はシリアル化されるときに JSON 配列としてシリアル化され、それぞれの配列項目は指定された type となります。
RemoveClaimValue()
Method RemoveClaimValue(name As %String)
name 引数で指定したクレームを削除することで、ClaimValues プロパティを更新します。
GetClaimValue()
Method GetClaimValue(name As %String, output type) As %String
ClaimValues プロパティを調べて、name 引数で指定されたクレームの値を返します。出力として返される type 引数はクレームの型を示します。SetClaimValue() を参照してください。
NextClaimValue()
Method NextClaimValue(name As %String) As %String
指定されたクレームの後にある (ClaimValues プロパティの) 次のクレームの名前を返します。
JWT で使用するキーの回転
ほとんどの場合、新しい公開/秘密鍵ペアを承認サーバに生成させることができます。これは、非対称の RS256、RS384、および RS512 の各アルゴリズムに使用する RSA 鍵にのみ適用されます。(例外は、[X509 証明書] として、[ダイナミック登録以外のソース] を指定する場合です。この場合、新しいキーは生成できません。)
新しい公開/秘密鍵ペアの生成は、キーの回転と呼ばれています。このプロセスは、新しい秘密 RSA 鍵および関連する公開 RSA 鍵を秘密と公開の JWKS に追加します。
承認サーバでキーの回転を実行すると、承認サーバは新しい秘密 RSA 鍵を使用して、クライアントに送信する JWT に署名します。同様に、承認サーバは新しい公開 RSA 鍵を使用して、クライアントに送信する JWT を暗号化します。承認サーバは、クライアントから受信した JWT を解読するために新しい RSA 鍵を使用しますが、これが失敗したら古い RSA 鍵を使用するため、古い公開 RSA 鍵を使用して作成された JWT を解読できます。
最後に、クライアントから受信した署名済み JWT を承認サーバが検証できない場合、承認サーバにクライアントの公開の JWKS の URL があると、承認サーバは新しい公開の JWKS を取得し、署名の検証を再試行します。(ダイナミック Discovery を使用した場合や、構成で [URL から JWKS] オプションが指定された場合、承認サーバはクライアントの公開の JWKS の URL を持っています。それ以外の場合には承認サーバはこの URL を持っていません。)
承認サーバのキーを回転するには、以下の手順を実行します。
-
[システム管理]→[セキュリティ]→[OAuth 2.0]→[サーバ構成] を選択します。
承認サーバの構成が表示されます。
-
[キーの回転] ボタンを選択します。
Note:
対称の HS256、HS384、および HS512 の各アルゴリズムは、常に対称鍵としてクライアントの秘密鍵を使用します。