すべてのプロダクト
Search
ドキュメントセンター

Resource Access Management:OktaからOIDCベースのSSOを実装する

最終更新日:Apr 29, 2025

このトピックでは、OktaからAlibaba CloudへのOpenID Connect (OIDC) ベースのシングルサインオン (SSO) の実装方法の例を示します。 その後、Oktaに登録されているアプリケーションは、Security Token Service (STS) トークンを使用してAlibaba Cloudリソースに安全にアクセスできます。

前提条件

OIDCアプリケーションはOktaに登録されています。 発行者のURLとアプリケーションのクライアントIDを取得する。 この例では、次のデータが使用されます。

  • 発行者のURLは https://dev-xxxxxx.okta.com です。

  • クライアントIDは0oa294vi1vJo Clev **** です。

ステップ1: Alibaba CloudでのOIDC IDプロバイダー (IdP) の作成

このステップでは、TestOidcProviderという名前のOIDC IdPが作成されます。 発行者のURLhttps://dev-xxxxxx.okta.com で、クライアントID0oa294vi1vJo Clev **** です。

  1. にログインします。RAMコンソールAlibaba Cloudアカウントを使用します。

  2. 左側のナビゲーションウィンドウで、統合 > SSO.

  3. [ロールベースSSO] タブで、[OIDC] タブをクリックします。 次に、[IdPの追加] をクリックします。

  4. On theIdPの作成ページで、次のパラメーターを設定します。

    パラメーター

    説明

    IdP名

    名前はAlibaba Cloudアカウント内で一意である必要があります。

    IdP URL

    外部IdPによって提供される発行者のURL。 外部IdPによって提供される発行者のURL。 発行者のURLはhttpsで始まり、有効なURLである必要があります。 URLには、疑問符 (?) に続くクエリパラメーター、アットマーク (@) で識別されるログオン情報、または番号記号 (#) で識別されるフラグメントを含めることはできません。

    指紋

    外部IdPのHTTPS証明書に基づいて生成されるフィンガープリント。 指紋を使用して、発行者のURLがハイジャックされたり改ざんされたりするのを防ぐことができます。 Alibaba Cloudはフィンガープリントを計算します。 コンピューターで指紋を計算することをお勧めします。 たとえば、OpenSSLを使用してフィンガープリントを計算できます。 次に、計算結果とAlibaba Cloudが提供する計算結果を比較できます。 OpenSSLの詳細については、OpenSSLの公式Webサイトをご覧ください。 計算結果が異なる場合、発行者のURLが攻撃された可能性があります。 有効な指紋を入力してください。

    説明

    IdPの証明書をローテーションする場合は、新しい証明書のフィンガープリントを生成し、ローテーションの前にRAMコンソールで作成したOIDC IdPにフィンガープリントを追加することをお勧めします。 少なくとも1日後、証明書をローテーションします。 Security Token Service (STS) トークンを取得した後、以前のフィンガープリントを削除できます。

    クライアントID

    アプリケーションを外部IdPに登録するときに生成されるID。 外部IdPからOIDCトークンを申請するときは、クライアントIDを使用する必要があります。 クライアントIDは、発行されるOIDCトークンのaudフィールドで指定されます。 OIDC IdPを作成するときは、クライアントIDを設定する必要があります。 OIDCトークンを使用してSTSトークンを取得する場合、Alibaba Cloudは、audフィールドで指定されたクライアントIDがOIDC IdPで設定したクライアントIDと同じであるかどうかを確認します。 クライアントIDが同じである場合にのみ、RAMロールを引き受けることができます。

    複数のクライアントがAlibaba Cloudリソースにアクセスする必要がある場合は、複数のクライアントIDを設定できます。 最大20のクライアントIDを設定できます。

    補足

    OIDC IdPの説明。

  5. クリックOK.

手順2: Alibaba CloudでOIDC IdPのRAMロールを作成する

このステップでは、testoidcという名前のRAMロールが作成され、ステップ1で作成したTestOidcProvider OIDC IdPが選択されます。

  1. にログインします。RAMコンソール管理者権限を持つRAMユーザーとして

  2. 左側のナビゲーションウィンドウで、アイデンティティ > ロール.

  3. On theロールページをクリックします。ロールの作成.

  4. On theロールの作成ページを選択します。IdP[信頼できるエンティティの選択] セクションで、次へ.

  5. を指定します。Specify theRAMロール名パラメーターを使用します。

  6. IdP TypeパラメーターにOIDCを選択します。

  7. 信頼できるIdPを選択し、条件を指定します。

    次の表に、サポートされる条件を示します。

    条件キー

    説明

    必須

    oidc:iss

    発行者。 RAMロールを引き受けることができるのは、RAMロールを引き受けるために使用するOIDCトークンのissフィールドがこの条件を満たしている場合のみです。

    条件演算子はStringEqualsでなければなりません。 値は、選択したOIDC IdPに指定した発行者のURLである必要があります。 この条件を指定すると、信頼できるIdPによってOIDCトークンが発行された場合にのみ、OIDCトークンを使用してRAMロールを引き受けることができます。

    https://dev-xxxxxx.okta.com

    oidc:aud

    聴衆。 RAMロールを引き受けることができるのは、RAMロールを引き受けるために使用するOIDCトークンのaudフィールドがこの条件を満たしている場合のみです。

    条件演算子はStringEqualsでなければなりません。 値は、選択したOIDC IdPに指定する1つ以上のクライアントIDにすることができます。 この条件を指定すると、指定したクライアントIDを使用してOIDCトークンが生成された場合にのみ、OIDCトークンを使用してRAMロールを引き受けることができます。

    0oa294vi1vJo Clev ****

    oidc: サブ

    主題。 RAMロールを引き受けることができるのは、RAMロールを引き受けるために使用するOIDCトークンのサブフィールドがこの条件を満たしている場合のみです。

    条件演算子は、すべての型の文字列にすることができます。 値は最大10人の被験者にすることができます。 この条件を指定して、RAMロールを引き受けるために使用できるIDをさらに制限できます。 この条件を指定しないままにすることもできます。

    任意

    00u294e3mzNXt4Hi ****

  8. クリックOK.

  9. クリック閉じる.

ステップ3: RAMロールに権限を付与する

ビジネス要件に基づいてAlibaba Cloudリソースにアクセスするために、ステップ2で作成したtestoidcという名前のRAMロールに権限を付与できます。

  1. にログインします。RAMコンソールRAM管理者として

  2. 左側のナビゲーションウィンドウで、アイデンティティ > ロール.

  3. On theロールページで、管理するRAMロールを見つけて、をクリックします。権限付与で、アクション列を作成します。

    image

    複数のRAMロールを選択し、RAMロールリストの下部にある [権限の付与] をクリックして、一度に複数のRAMロールに権限を付与することもできます。

  4. では、権限付与パネルで、RAMロールに権限を付与します。

    1. Resource Scopeパラメーターを設定します。

      • アカウント: 権限付与は、現在のAlibaba Cloudアカウントで有効になります。

      • リソースグループ: 権限付与は、特定のリソースグループに対して有効になります。

        説明

        [リソーススコープ] パラメーターで [リソースグループ] を選択した場合、必要なクラウドサービスがリソースグループをサポートしていることを確認します。 詳細については、「リソースグループで動作するサービス」をご参照ください。

    2. Principalパラメーターを設定します。

      プリンシパルは、権限を付与するRAMロールです。 現在のRAMロールが自動的に選択されます。

    3. Policyパラメーターを設定します。

      ポリシーは一連のアクセス権限です。 一度に複数のポリシーを選択できます。

      • システムポリシー: Alibaba Cloudによって作成されたポリシー。 これらのポリシーは使用できますが、変更することはできません。 ポリシーのバージョン更新は、Alibaba Cloudによって管理されます。 詳細については、「RAMで動作するサービス」をご参照ください。

        説明

        システムは、AdministratorAccessやAliyunRAMFullAccessなどのリスクの高いシステムポリシーを自動的に識別します。 リスクの高いポリシーをアタッチして、不要な権限を付与しないことを推奨します。

      • カスタムポリシー: ビジネス要件に基づいてカスタムポリシーを管理および更新できます。 カスタムポリシーを作成、更新、削除できます。 詳細については、「カスタムポリシーの作成」をご参照ください。

    4. [権限付与] をクリックします。

  5. クリック閉じる.

ステップ4: OktaでOIDCトークンを発行する

OIDCを使用してAlibaba Cloud管理コンソールにログインすることはできません。 したがって、プログラムアクセスを使用してOIDCベースのSSOを実装する必要があります。 OIDCトークンを取得するには、Open authorization (OAuth) を使用して承認を完了する必要があります。 したがって、OktaなどのOIDC IdPからOIDCトークンを取得するには、OAuth 2.0を使用する必要があります。 OAuthは、承認コードフローなどのさまざまなフローをサポートします。 詳細については、「承認コードフロー」をご参照ください。 しかしながら、認証コードフローは複雑である。 次のセクションでは、暗黙のフローを使用して、OIDCトークンを取得してSSOを実装する方法を説明します。 暗黙のフローの一部の操作については、このトピックでは説明しません。 暗黙的なフローの詳細については、「暗黙的なフロー」をご参照ください。

  1. Oktaによって発行されたOIDCトークンを受け取るwebアプリケーションをビルドします。

    この例では、Java Spring BootとThymeleafを使用して構築された単純なwebアプリケーションを使用しています。 webアプリケーションはコンピューターにデプロイされ、ポート8080経由でアクセスでき、localhostは127.0.0.1に解決されます。 したがって、コンピューターのブラウザーでlocalhost:8080と入力して、webアプリケーションにアクセスできます。 次のサンプルコードを提供します。

    • 静的ページのサンプルコード

      OAuth 2.0では、Oktaがwebアプリケーションに送信するコールバック情報が、コールバックURLのフラグメントコンポーネントで渡される必要があります。 webページを作成し、フラグメントコンポーネントからOIDCトークンを取得できます。 この例では、単純な静的ページが作成されます。 次に、フラグメントコンポーネントを透過的に渡すことができます。 このページの完全なURLは、http:// localhost:8080/accessTokenCallbackです。これは、Oktaのアプリケーション用に設定されたコールバックURL redirect_uriでもあります。

      <!DOCTYPE HTML>
      <html xmlns:th=" http://www.thymeleaf.org ">
          <head>
              <script>
                  window.onload = function () {
                      let fragment = window.location.hash.substring (1);
                      window.location.href = "/receiveAccessToken?" + フラグメント;
                  };
              </script>
          </head>
      </html> 
    • クラスのサンプルコード

      静的ページのコントローラとしてクラスが作成されます。

      パッケージcom.aliyun.oauthtest;
      
      org.springframework.stereotype.Controllerをインポートします。org.springframework.web.bind.annotation.RequestMappingをインポートします。@ コントローラー
      public class CallbackController {
          @ RequestMapping("accessTokenCallback")
          public String callback() {
              "accessTokenCallback" を返します。
          }
      }
  2. Oktaにログインし、OktaからOIDCトークンを申請します。

    Oktaにログインする必要があります。 次に、URL https://dev-xxxxxx.okta.com/oauth2/v1/authorize?client_id=0oa294vi1vJoClev ****&scope=openid&response_type=token % 20id_token&state=testState&nonce=a_unique_nonce_1&redirect_uri=http % 3A % 2F % 2Flocalhost % 3A8080% 2FaccessTokenCallbackを構築してアクセスできます。手順1でビルドされたwebアプリケーション。

    次のリストは、URLのパラメーターについて説明しています。

    • client_id: このパラメーターをOktaに登録されているOIDCアプリケーションのクライアントIDに設定します。

    • scope: このパラメーターをopenidに設定します。

    • response_type: 暗黙的なフローで、このパラメーターをtoken id_tokenに設定します。

    • state: OIDCアプリケーションの現在のステータスを指定します。 このパラメーターは、ビジネス要件に基づいて設定できます。

    • nonce: このパラメーターは、リプレイ攻撃を防ぐために使用されます。 このパラメーターは、ビジネス要件に基づいて設定できます。

    • redirect_uri: このパラメーターを、access_tokenまたはid_tokenの受信に使用するコールバックURLに設定します。 この例では、このパラメーターを、サブステップ1で作成したwebアプリケーションのURLに設定します。

    この例では、Oktaにログインしています。 したがって、指定されたredirect_uriに基づいてコールバックURLにリダイレクトされます。 次のURLのid_tokenの値は、OIDCトークンです。

    HTTP/1.1 302が見つかりました
    場所: http:// localhost:8080/accessTokenCallback#id_token=eyJraWQiOiJ6OUV0e ****&access_token=eyJraWQiOiJseEQ3R ****&token_type=Bearer&expires_in=3600&scope=openid&state=testState 
  3. OIDCトークンを解析します。

    サブステップ2で取得した結果を解析し、ヘッダーペイロードに関する詳細を照会できます。

    リクエストの例

    パッケージcom.aliyun.oauthtest;
    
    java.util.Base64をインポートします。java.util.Base64.Decoderをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。java.util.TreeMapをインポートします。com.alibaba.fastjson.JSONをインポートします。com.alibaba.fastjson.JSONObjectをインポートします。org.springframework.web.bind.annotation.RequestMappingをインポートします。org.springframework.web.bind.annotation.RequestMethodをインポートします。org.springframework.web.bind.annotation.RequestParamをインポートします。org.springframework.web.bind.annotation.RestControllerをインポートします。@ RestController
    public class ClientAppController {
    
    
        @ RequestMapping(value = "/receiveAccessToken" 、method = {RequestMethod.POST、RequestMethod.GET} 、
                produces = "application/json")
        public Map<String, Object> receiveAccessToken(@ RequestParam("access_token")) String accessToken,
                                                      @ RequestParam("id_token") 文字列idToken、
                                                      @ RequestParam("token_type") 文字列tokenType、
                                                      @ RequestParam("expires_in") 長いexpireTime、
                                                      @ RequestParam("scope") 文字列スコープ、
                                                      @ RequestParam("state") String state) 
        {
            Map<String, Object> result = new TreeMap<>();
            result.put("access_token", accessToken);
            result.put("id_token", idToken);
            result.put("token_type", tokenType);
            result.put("expires_in", "+ expireTime);
            result.put("scope", scope);
            result.put("state", state);
    
            String[] jwt = idToken.split("\\.");
            デコーダデコーダ=Base64.getDecoder();
            result.put("id token jwt header", JSON.parse(new String(decoder.de code(jwt[0]))));
            result.put("id token jwt payload", JSON.parse(new String(decoder.de code(jwt[1]))));
            result.put("id token jwt signature", jwt[2]);
            return result;
    
        }
    }

    レスポンス例:

    {
        "id token jwt header": {
            "kid": "z9EtyT345d-JLIJo2-5ySDO27LG4FPeOotbwJPT ****" 、
            "alg": "RS256"
        },
        "id token jwt payload": {
            "at_hash": "KKsdN3prZWTvBEMn-g ****" 、
            "sub": "00u294e3mzNXt4Hi ****" 、
            "aud": "0oa294vi1vJo Clev ****" 、
            "ver": 1、
            "idp": "0oa294iehxjUCZIO ****" 、
            "amr": [
                "pwd"
            ],
            "auth_time": 1636373097、
            "iss": " https://dev-xxxxxx.okta.com " 、
            "exp": 1636377759、
            "iat": 1636374159、
            "nonce": "a_unique_nonce_1" 、
            "jti": "ID.lmSU5AD2iKLCVu6_KLMIr52dpCprncxW38v-NCA ****"
        },
        "id token jwt signature": "ZEJEGIv4Zoau63 ****" 、
        "access_token": "eyJraWQiOiJseEQ3R ****" 、
        "expires_in": "3600" 、
        "id_token": "eyJraWQiOiJ6OUV0e ****" 、
        "scope": "openid" 、
        "state": "testState" 、
        "token_type": "Bearer"
    } 

ステップ5: OIDCトークンを使用してSTSトークンを取得する

STSトークンを取得するには、AssumeRoleWithOIDC操作を呼び出します。 リクエストで、ステップ4で取得した解析されていないOIDCトークンを指定します。

リクエストの例

public static void main(String[] args)
{
    IAcsClientクライアント=初期化 ();
    String jwtToken = "eyJraWQiOiJ6OUV0e ****"; // Oktaから取得した解析されていないOIDCトークン。 トークンはid_tokenの値です。 
    AssumeRoleWithOIDCRequest request = new AssumeRoleWithOIDCRequest();
    request.setDurationSeconds(3600L);
    request.setOIDCProviderArn("acs:ram::113511544585 ****:oidc-provider/TestOidcProvider");
    request.setOIDCToken(jwtToken);
    request.setRoleArn("acs:ram::113511544585 ****:role/testoidc");
    request.setRoleSessionName("TestOidcAssumedRoleSession");
    try
    {
        AssumeRoleWithOIDCResponse resp = client.getAcsResponse (リクエスト);
        System.out.println("success requestId: " + resp.getRequestId());
        System.out.println("success assume role arn: " + resp.getAssumedRoleUser().getArn());
        System.out.println("success sts credential accessKey id: " + resp.getCredentials().getAccessKeyId());
        System.out.println("success sts credential accessKey secret: " + resp.getCredentials().getAccessKeySecret());
        System.out.println("success resp: " + JSON.toJSONString(resp));
    }
    catch(ClientException | SystemException e)
    {
        e.printStackTrace();
    }
}

レスポンス例:

success requestId: 3D57EAD2-8723-1F26-B69C-F8707D8B565D
success assume role arn: acs:ram::113511544585 ****:role/testoidc/TestOidcAssumedRoleSession
success stsクレデンシャルaccessKey id: STS.NUgYrLnoC37mZZCNnAbez ****
success stsクレデンシャルaccessKey secret: CVwjCkNzTMupZ8NbTCxCBRq3K16jtcWFTJAyBEv2 ****
resp成功:
{
    "AssumedRoleUser":
    {
        "Arn": "acs:ram::113511544585 ****:role/testoidc/TestOidcAssumedRoleSession" 、
        "AssumedRoleId": "33157794895460 ****:TestOidcAssumedRoleSession"
    },
    「資格情報」:
    {
        "AccessKeyId": "STS.NUgYrLnoC37mZZCNnAbez ****" 、
        "AccessKeySecret": "CVwjCkNzTMupZ8NbTCxCBRq3K16jtcWFTJAyBEv2 ****" 、
        "有効期限": "2021-10-20T04:27:09Z" 、
        "SecurityToken": "CAIShwJ1q6Ft5B2yfSjIr ****"
    },
    "OIDCTokenInfo":
    {
        "ClientIds": "0oa294vi1vJo Clev ****" 、
        "発行者": " https://dev-xxxxxx.okta.com " 、
        「件名」: 「00u294e3mzNXt4Hi **** 」
    },
    "RequestId": "3D57EAD2-8723-1F26-B69C-F8707D8B565D"
} 

[資格情報] の情報は、STSトークンに関する情報です。

手順6: STSトークンを使用したAlibaba Cloudリソースへのアクセス

ステップ5で取得したSTSトークンを使用して、権限を持つAlibaba Cloudリソースにアクセスします。