トークン交換権限付与タイプ: UPSTのためのKerberosトークンの交換
Kerberosが認証プロバイダであり、KerberosトークンをIAMトークンまたはプリンシパルと交換してOCIサービスにアクセスする必要がある場合に、Kerberosトークン交換を使用します。IAMでKerberosトークンをOCIユーザー・プリンシパル・セッション・トークン(UPST)と交換します。
用語 | 説明 |
---|---|
Kerberos |
クロス・プラットフォーム認証のシングル・サインオン・システム。Kerberosプロトコルを使用すると、共有の秘密キー(対称キー)に依存する2つのエンティティ間で相互認証を実行できます。Kerberos認証では、クライアント、サーバーおよびそれらを仲介するための、キー配布センター(KDC)と呼ばれる信頼されたパーティが必要です。 次も必要です:
WS-SecurityのKerberos Token Profileを使用すると、ビジネス・パートナがサービス指向アーキテクチャ(SOA)でKerberosトークンを使用できるようになります。 |
Kerberosキー配布センター(KDC) | サードパーティーの認証サーバー。 |
Active Directory (AD) | KDCサーバーのリポジトリ。 |
Keytab |
特定のプリンシパルのパスワード・チャレンジのかわりに使用できる実際の暗号化キーを格納するファイル。キータブ・ファイルは、非対話型のユース・ケースに役立ちます。 ヒント: KDC管理ツールを使用してキータブ・ファイルを作成できます。keytabの作成時に、暗号化タイプを指定できます。次の暗号化タイプを使用します: |
シンプルで保護されたGSSAPIネゴシエーション・メカニズム(SPNEGO) |
Simple and Protected GSSAPI Negotiation Mechanism(SPNEGO)は、クライアント/サーバー・ソフトウェアがセキュリティ・テクノロジの選択をネゴシエーションするために使用するGSSAPIの疑似メカニズムです。 Kerberosチケットは、トークンがHTTPベースのアプリケーション・レイヤーで動作するように、SPNEGOトークンの一部としてラップされます。 SPNEGOトークンのフォーマットと詳細 SPNEGOトークン形式は、RFC 4178で定義されています。トークンは、次のフィールドを含むシリアライズされたデータ構造です。
SPNEGOトークンはASN.1でエンコードされます。次に、SPNEGOトークンの例を示します。
|
グサピ | 一般セキュリティ・サービス・アプリケーション・プログラム・インタフェース |
IAMトークン交換Service API | IAMアイデンティティ・ドメインOAuthサービス: /oauth2/v1/token 。APIは、標準のOAuthベースの認証ヘッダー/ペイロードとOCI署名の両方を受け入れます。アイデンティティ・ドメインでOAuthクライアントを使用してREST APIにアクセスする方法を学習するには、OAuth 2を使用したREST APIへのアクセスを参照してください。 |
アイデンティティ伝播の信頼構成 | アイデンティティ伝播信頼構成を使用して、OCIアイデンティティと外部アイデンティティ・プロバイダ間の信頼を確立し、外部アイデンティティ・プロバイダ・トークンと、外部アイデンティティ・プロバイダのユーザー・アイデンティティとIAMのユーザー・アイデンティティのマッピングを検証します。また、アイデンティティ伝播の信頼によって、外部アイデンティティ・プロバイダからOCIへのアイデンティティ伝播も容易になります。/IdentityPropagationTrust エンドポイント設計は汎用であり、任意のクラウド・プロバイダと連携します。アイデンティティ伝播信頼構成を作成するには、ステップ6: アイデンティティ伝播信頼構成の作成を参照してください。 |
サービス・ユーザー | 対話型ログイン権限のないユーザー。これらのサービス・ユーザーは、グループおよびサービス・ロールに付与できます。アプリケーションは、これらのサービス・ユーザーを使用することも、ログイン・ユーザーがそれらのユーザーを偽装して一時的なUPSTを取得することもできます。サービス・ユーザーの使用はオプションです。サービス・ユーザーの使用の詳細は、ステップ5: サービス・ユーザーの使用(オプション)を参照してください。 |
ユーザー・プリンシパル・セッション・トークン(UPST) | IAM生成トークン。セキュリティ・トークンとも呼ばれます。認証済サービス・ユーザーを表します。 |
Kerberosトークンの交換ステップ
次のステップを使用して、KerberosトークンをUPSTと交換します。
ステップ1: Vaultの作成およびKeytabファイルの内容の追加
Vaultを作成し、キータブ・ファイルのコンテンツをbase64エンコード文字列として追加します。ノート: IAMは、keytabファイルをファイル・システムに格納しません。
ガイドとして次のステップを実行します。
- Vaultの作成Vaultの作成を参照してください。
- keytabの内容をBase64形式で読み取ります。
- Vaultに移動し、そのまま格納します。シークレットの作成時に、必ずBase64をシークレット・タイプ・テンプレートとして確認してください。Vaultでのシークレットの作成を参照してください。
ステップ2: 必要なIAMポリシーの作成
アイデンティティ・ドメイン・リソースがVaultにアクセスできるように、テナンシにIAMポリシーを作成します。これにより、IAMはVaultからkeytab構成を取得できます。次の例をガイドとして使用できます。
allow resource iam-domain <domain_displayName> to read secrets from vault in compartment <compartment_ocid> where all {target.secret.id = <secret_ocid_where_the_keytab_is_present>}
ステップ3: アイデンティティ・ドメイン・アプリケーションの作成
アイデンティティ・ドメインの機密アプリケーションを作成します。アプリケーションを作成したら、クライアントIDとクライアントシークレットをセキュアな場所に保存します。機密アプリケーションの追加に関する項を参照してください。
ステップ4: 特定のユーザー・プリンシパルのSPNEGOトークンの生成
- Javaコードを使用してKDCサーバーに接続し、SPNEGOトークンを生成します。
- そのSPNEGOトークンをコピーして、トークン・リクエストを形成します。
次のJavaコード例をガイドとして使用します。
package com.oracle;
import com.sun.security.auth.module.Krb5LoginModule;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
import javax.security.auth.Subject;
import java.io.IOException;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class GenerateSpnegoToken {
static String servicePrincipal = "HTTP/iamtesp@WINDOWSKDCSERVER.COM";
static String userPrincipal = "HTTP/<sample-job>@WINDOWSKDCSERVER.COM";
static String userPrincipalKeyTab = "keytabs/ms/<sample-job>.keytab";
public static void main(String[] args) throws IOException {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("sun.security.spnego.debug", "true");
System.setProperty("java.security.krb5.conf", "ms_krb5.conf");
String spnegoToken = generateSpnegoToken();
}
private static String generateSpnegoToken() {
Subject subject = getAuthenticateSubject();
return Subject.doAs(
subject,
(PrivilegedAction<String>)
() -> {
String SPNEGO_OID = "1.3.6.1.5.5.2";
String KRB5_MECHANISM_OID = "1.2.840.113554.1.2.2";
String KRB5_PRINCIPAL_NAME_OID = "1.2.840.113554.1.2.2.1";
try {
// Create GSS context for the service principal and the logged-in user
Oid krb5Mechanism = new Oid(KRB5_MECHANISM_OID);
Oid krb5PrincipalNameType = new Oid(KRB5_PRINCIPAL_NAME_OID);
Oid spnegoOid = new Oid(SPNEGO_OID);
GSSManager manager = GSSManager.getInstance();
GSSName gssServerName =
manager.createName(servicePrincipal, krb5PrincipalNameType, krb5Mechanism);
GSSContext gssContext =
manager.createContext(
gssServerName, spnegoOid, null, 240000);
gssContext.requestMutualAuth(true);
gssContext.requestCredDeleg(true);
gssContext.requestLifetime(10);
// Generate the SPNEGO token
byte[] token = new byte[0];
token = gssContext.initSecContext(token, 0, token.length);
return Base64.getEncoder().encodeToString(token);
} catch (GSSException e) {
throw new RuntimeException(e);
}
});
}
private static Subject getAuthenticateSubject() {
final Map<String, String> options = new HashMap<>();
options.put("keyTab", userPrincipalKeyTab);
options.put("principal", userPrincipal);
options.put("doNotPrompt", "true");
options.put("isInitiator", "true");
options.put("refreshKrb5Config", "true");
options.put("storeKey", "true");
options.put("useKeyTab", "true");
// Execute the login
Subject subject = new Subject();
Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
krb5LoginModule.initialize(subject, null, new HashMap<String, String>(), options);
try {
krb5LoginModule.login();
krb5LoginModule.commit();
} catch (Exception e) {
throw new RuntimeException(e);
}
Set<Principal> principals = (Set<Principal>) subject.getPrincipals();
Iterator<Principal> iterator = principals.iterator();
while (iterator.hasNext()) {
System.out.println("\nprincipal : " + ((Principal) iterator.next()));
}
return subject;
}
}
ステップ5: サービス・ユーザーの使用(オプション)
サービス・ユーザーは、属性serviceUser
がtrue
に設定されているアイデンティティ・ドメイン・ユーザーです。
サービス・ユーザーの使用はオプションです。ユーザーの偽装を信頼構成の一部として使用する場合は、サービス・ユーザーが必要です。それ以外の場合は、他のアイデンティティ・ドメイン・ユーザーが使用されます。サービス・ユーザーを作成、置換、更新または削除できるのは、アイデンティティ・ドメイン管理者のみです。他の管理者は、サービス・ユーザーとその属性を読み取ることができます。
サービス・ユーザーを使用するには、対話型ログイン権限のないユーザーを作成します。これらのサービス・ユーザーは、グループおよびサービス・ロールに付与できます。アプリケーションでこれらのサービス・ユーザーを使用することも、ログイン・ユーザーがそれらを偽装して一時的なUPSTトークンを取得することもできます。
サービス・ユーザーには、次の特徴があります。
- userNameが必要です。名および姓は必要ありません。
- 電子メール・アドレスを指定できます(オプション)。
- グループおよびアプリケーション・ロールのメンバーにできます。
- APIキーを使用できません。
- セルフサービス・エンドポイントを使用できません。
- パスワードおよびパスワード・ポリシーを適用できません。
リクエストの例: サービス・ユーザーの作成
次に、サービス・ユーザーの作成に必要な最小属性を持つリクエストの例を示します。
## POST on https://<domainURL>/admin/v1/Users
## Payload:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User": {
"serviceUser": true
},
"userName": "myServiceUserName"
}
レスポンスの例: サービス・ユーザーの作成
次に、サービス・ユーザー作成時のレスポンスの例を示します。
{
"idcsCreatedBy": {
"type": "App",
"display": "idcsadmin"
},
"id": "<user_id>",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User": {
"isFederatedUser": false,
"isGroupMembershipSyncedToUsersGroups": true,
"serviceUser": true
},
"meta": {
"created": "2023-12-07T06:52:55.380Z",
"lastModified": "2023-12-07T06:52:55.380Z",
"version": "<version>",
"resourceType": "User",
"location": "https://<domainURL>/admin/v1/Users/<user_id>"
},
"active": true,
"idcsLastModifiedBy": {
"display": "idcsadmin",
"type": "App"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User": {
"locked": {
"on": false
}
},
"ocid": "ocid1.user.region1...<ocid>",
"userName": "myServiceUserName",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:capabilities:User",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User"
]
}
ステップ6: アイデンティティ伝播信頼構成の作成
アイデンティティ伝播の信頼構成は、OCIアイデンティティと外部クラウド・プロバイダ間の信頼、クラウド・プロバイダ・トークンの検証、およびクラウド・プロバイダのユーザー・アイデンティティとアイデンティティ・ドメインのservice
ユーザー・アイデンティティのマッピングを確立するために使用されます。
属性 | 必須? | 説明と例 |
---|---|---|
名前 | はい |
信頼の名前。 |
型 | はい |
トークン・タイプ:
|
発行者 | はい |
発行者を使用して、信頼の識別情報を検索します。たとえば、サービス・プリンシパル 例: |
アクティブ | はい |
有効な場合は、 無効な場合、 |
oauthClients | はい |
特定の信頼できるパートナのトークンの取得を許可されているOAuthクライアントのリスト。 例:
|
allowImpersonation (serviceUserを使用) | いいえ |
ブール値。結果のUPSTにサブジェクトとして認証済ユーザーを含めるか、IAMでサービス・ユーザーを偽装するかを指定します。 |
impersonatingServiceUser |
はい( |
トークン要求名および値条件に基づいて、結果として生成されるプリンシパルが偽装されるかどうかを指定します。次のことができます:
例:
偽装が許可されている場合、結果のOCIセキュリティ・トークン(UPST)には、元の認証済ユーザー関連クレーム(
|
keytab |
はい(トークン・タイプが |
Vaultからkeytab構成を取得します。 重要:
|
リクエストの例: アイデンティティ伝播信頼構成の作成
## POST on https://<domainURL>/admin/v1/IdentityPropagationTrusts
## Payload:
{
"active": true,
"allowImpersonation": false,
"issuer": "idcs_psr_itp",
"name": "<identity_propagation_trust_name>",
"oauthClients": [
"<oauthclient-id>"
],
"keytab": {
"secretOcid": "<secret_ocid>"
},
"subjectMappingAttribute": "userName",
"subjectType": "User",
"type": "SPNEGO",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:IdentityPropagationTrust"
]
}
レスポンスの例: アイデンティティ伝播信頼構成の作成
"response": {
"name": "<identity_propagation_trust_name>",
"type": "<token_type>",
"issuer": "idcs_psr_itp",
"accountId": "<example_account_id>",
"subjectClaimName": "cognito:username",
"subjectMappingAttribute": "username",
"subjectType": "User",
"clientClaimName": "appId",
"clientClaimValues": ["<client_claim_value>"],
"active": true,
"publicKeyEndpoint": "https://example.identityprovider.com/publickey/<publickey_value>",
"publicCertificate": "<public_certificate_value>",
"oauthClients": ["<oauthclient-id>"],
"allowImpersonation": true,
"impersonationServiceUsers": [
{
"rule": "groups co \"network-admin\"",
"userId": "<user_id>"
},
{
"rule": "groups co \"tenancy-admin\"",
"userId": "<user_id>"
}
],
"keytab": {
"secretOcid": "<secret_ocid>",
"secretVersion": "<secret_version>"
},
"clockSkewSeconds": 60,
"id": "<identity_propagation_trust_id>",
"meta": {
"created": "2023-11-09T23:26:53.224Z",
"lastModified": "2023-11-09T23:26:53.224Z",
"resourceType": "IdentityPropagationTrust",
"location": "http://example.hostname.com:8990/admin/v1/IdentityPropagationTrusts/<identity_propagation_trust_id>"
},
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:IdentityPropagationTrust"
],
"idcsCreatedBy": {
"value": "<app_id>",
"display": "admin",
"type":"App",
"$ref": "http://example.hostname.com:8990/admin/v1/Apps/<app_id>"
},
"idcsLastModifiedBy": {
"value": "<app_id>",
"display": "admin",
"type":"App",
"$ref": "http://example.hostname.com:8990/admin/v1/Apps/<app_id>"
}
}
ステップ7: OCIを最新の状態に
リクエスト・パラメータ | 有効な値 |
---|---|
|
|
|
|
|
公開キー・ワークフロー:
|
|
|
|
トークン・タイプ:
|
|
トークン・タイプが 例:
|
UPSTトークン・リクエストの例: OCI署名ベース
OCI署名ベースのcURLリクエストの例を次に示します。
## OCI Signature Based Request
curl -X POST -sS https://<domainURL>/oauth2/v1/token -i
-H 'date: Wed, 06 Dec 2023 01:17:33 GMT'
-H 'x-content-sha256: <key>'
-H 'content-type: application/x-www-form-urlencoded;charset=utf-8'
-H 'content-length: 197'
-H 'Authorization: Signature version="1",keyId="<key_id>",algorithm="rsa-sha256",headers="(request-target) date host x-content-sha256 content-type content-length",signature="a+aH0b...TLtPA=="' --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'requested_token_type=urn:oci:token-type:oci-upst' \
--data-urlencode 'public_key=<public_key>' \
--data-urlencode 'subject_token=<subject_token>' \
--data-urlencode 'subject_token_type=spnego' \
--data-urlencode 'issuer=<Issuer stored in the Identity Trust Propagation. For example, examplead@kdcserver.com>' -k
{
"token": "<token_id>"
}
UPSTトークンのリクエストの例: アイデンティティ・ドメイン・アプリケーションベース
次に、OCIアイデンティティ・ドメイン・アプリケーションベースのcURLリクエストの例を示します。
## IAM Domain App Based Request. Note that client credentials can be sent as part of basic authn header or in the payload.
curl --location ' https://<domainURL>/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <auth_code>' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'requested_token_type=urn:oci:token-type:oci-upst' \
--data-urlencode 'public_key=<public_key>' \
--data-urlencode 'subject_token=<subject_token>' \
--data-urlencode 'subject_token_type=spnego' \
--data-urlencode 'issuer=<Issuer stored in the Identity Trust Propagation. For example, examplead@kdcserver.com>' -k
{
"token": "<token_id>"
}