トークン検証

トークンを検証する理由Webアプリケーションでは、資格証明を直接チェックするときに、表示されるユーザー名とパスワードが、保持しているユーザー名とパスワードに対応していることを確認します。クレーム・ベースのIDを使用する場合は、そのジョブをアイデンティティ・プロバイダにアウトソーシングします。

RAW資格証明の検証から、リクエスト元が優先アイデンティティ・プロバイダを経由して正常に認証されたことの確認に責任が変わります。アイデンティティ・プロバイダは、トークンを発行することで、認証が成功したことを表します。情報を使用する前、またはユーザーが認証したアサーションとして使用する前に、その情報を検証する必要があります。

OpenID検出文書

OpenID Connect 1.0プロトコルは、ユーザー情報、トークンおよび公開キーを含むリソースのリクエストとユーザーの認証に複数のエンドポイントを使用する必要がある、OAuth 2.0プロトコルの上にある単純なアイデンティティ・レイヤーです。これらのエンドポイントで、使用する必要があるエンドポイントを検出できるようにするために、OpenID Connectでは、既知の場所にあるJSONドキュメントである検出文書を使用できます。この検出文書には、認可、トークン、ユーザー情報および公開キー・エンドポイントのURIなど、OpenID Connectプロバイダの構成に関する詳細を提供するキー/値のペアが含まれます。IAMアイデンティティ・ドメインのOpenID Connectサービスの検出ドキュメントは、https://<domainURL>/.well-known/openid-configuration.から取得できます

Oracle Identity Cloud Service OpenID検出文書に関する項を参照してください。

アイデンティティ・トークンの検証

アイデンティティ(ID)トークンは、エンド・ユーザーに関するクレームを含む、整合性が確保された自己完結型のトークン(JSON Webトークン形式)です。認証されたユーザーのセッションを表します。したがって、アプリケーションがIDトークンの内容を信頼できるようにするには、トークンを検証する必要があります。たとえば、悪意のある攻撃者が以前に取得したユーザーのIDトークンをリプレイした場合、アプリケーションはトークンがリプレイされたこと、または期限切れになった後に使用されたことを検出し、認証を拒否する必要があります。

IDトークンはOpenID Connect標準で定義されており、認証を使用可能にするためのOpenID ConnectによるOAuth 2.0に対する主要な拡張機能です。IDトークンは機密性が高く、インターセプトされると誤用される可能性があります。これらのトークンが、HTTPS経由でのみ、POSTデータまたはリクエスト・ヘッダー内でのみ送信することで、安全に処理されるようにします。これらをサーバーに格納する場合も、安全に格納する必要があります。
  1. オーディエンス(aud)クレームの値に、アプリケーションのclient_id値が含まれることを検証します。aud (オーディエンス)クレームには、複数の要素を持つ配列を含めることができます。IDトークンに有効なオーディエンスとしてクライアントがリストされていない場合、またはクライアントから信頼されていない追加のオーディエンスが含まれる場合、IDトークンは拒否される必要があります。

  2. 現在の時刻が有効期限(exp)クレームで表される時刻より前であることを検証します。

  3. IDトークンが発行者によって正しく署名されていることを検証します。IAMアイデンティティ・ドメイン発行のトークンは、「検出ドキュメント」のjwks_uriフィールドで指定されたURIにある、いずれかの証明書を使用して署名されます。
    • SigningCert/jwkエンドポイント(たとえば、https://acme.identity.oraclecloud.com/admin/v1/SigningCert/jwk)からテナントのパブリック証明書を取得します。

      ノート

      アイデンティティ・ドメインは公開キーを頻繁に変更しないため、公開キーをキャッシュして、ほとんどの場合、ローカル検証は効率的に実行できます。これには、証明書の取得と解析、および署名をチェックするための適切な暗号コールが必要です:
    • 検証に使用可能なJWTライブラリを使用します(たとえば、Connect2idのJava用Nimbus JWTライブラリ)。使用可能なライブラリのリストは、「JWT」を参照してください。

      ノート

      署名検証が失敗した場合、bogusトークンを使用した攻撃に対する再フェッチが常に実行されるようにするには、一定の時間間隔に基づいて公開キーの再フェッチ/再キャッシュを実行する必要があります(例- 60分)。これにより、再フェッチは60分ごとに実行されます。

    package sample;
     
    import java.net.MalformedURLException;
    import java.net.URL;
     
    import com.nimbusds.jose.JWSAlgorithm;
    import com.nimbusds.jose.jwk.source.JWKSource;
    import com.nimbusds.jose.jwk.source.RemoteJWKSet;
    import com.nimbusds.jose.proc.JWSKeySelector;
    import com.nimbusds.jose.proc.JWSVerificationKeySelector;
    import com.nimbusds.jose.proc.SecurityContext;
    import com.nimbusds.jwt.JWTClaimsSet;
    import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
    import com.nimbusds.jwt.proc.DefaultJWTProcessor;
     
    public class TokenValidation {
     
        public static void main(String[] args) {
            try {
                String tokenValue = "eyJ4NXQjUzI1....W9J4oQ";
         
                ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
     
                // change t
                JWKSource keySource = new RemoteJWKSet(new URL("https://<domainURL>/admin/v1/SigningCert/jwk"));
     
                // The expected JWS algorithm of the token (agreed out-of-band)
                JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
     
                // Configure the JWT processor with a key selector to feed matching public
                // RSA keys sourced from the JWK set URL
                JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource);
                jwtProcessor.setJWSKeySelector(keySelector);
     
                // Process the token
                SecurityContext ctx = null; // optional context parameter, not required here
                JWTClaimsSet claimsSet = jwtProcessor.process(tokenValue, ctx);
                // Print out the token claims set
                System.out.println(claimsSet.toJSONObject());
                 
     
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
    }
  4. 発行者識別子(iss)クレームの値がiss (発行者)クレームの値(https://<domainURL>/)と完全に一致することを検証します

アクセス・トークンの検証

成功したOAuthトランザクションでは、APIコールの認証に使用するアクセス・トークンを発行するために、アイデンティティ・ドメインのOAuth認可サーバーが必要です。アクセス・トークンでは、クライアント・アプリケーションに発行される認可を表し、保護されているOAuthリソースにアクセスするために使用される資格証明が含まれます。認可エンドポイントから発行されたアクセス・トークンを検証するには、アプリケーション・クライアントは次の処理を実行する必要があります。
ノート

「アクセス・トークン」表を参照。
  1. アクセス・トークンが発行者によって適切に署名されていることを検証します。

    • SigningCert/jwkエンドポイント(たとえば、https://acme.identity.oraclecloud.com/admin/v1/SigningCert/jwk)からテナントのパブリック証明書を取得します。

      ノート

      アイデンティティ・ドメインは公開キーを頻繁に変更しないため、公開キーをキャッシュして、ほとんどの場合、ローカル検証は効率的に実行できます。これには、証明書の取得と解析、および署名をチェックするための適切な暗号コールが必要です:
    • 検証に使用可能なJWTライブラリを使用します(たとえば、Connect2idのJava用Nimbus JWTライブラリ)。使用可能なライブラリのリストは、「JWT」を参照してください。

    • 各ライブラリのAPI (たとえば、Nimbus SignedJWT APIを使用)に資格証明を渡します。

      PublicKey = x509Certificate.getPublicKey();
      // verify the signature.
      JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) (publicKey));
      boolean isTokenValid = signedJWT.verify(verifier);
      
      ノート

      署名検証が失敗した場合、bogusトークンを使用した攻撃に対する再フェッチが常に実行されるようにするには、一定の時間間隔に基づいて公開キーの再フェッチ/再キャッシュを実行する必要があります(例- 60分)。これにより、再フェッチは60分ごとに実行されます。
  2. 発行者識別子(iss)クレームの値がiss (発行者)クレームの値(https://<domainURL>/)と完全に一致することを検証します

  3. アクセス・トークンに、クライアントからのリクエストに応じたオーディエンス(aud)クレームがあることを検証します。audクレームの値は、クレームに応じて変更されます。audクレームは、複数のオーディエンスがある場合は配列になり、オーディエンスが1つのみの場合は文字列になります。

    audクレームは、IAMアイデンティティ・ドメイン・アプリケーションのリソース・サーバーのプライマリ・オーディエンスです。IAMアイデンティティ・ドメイン・アプリケーションにセカンダリ・オーディエンスが定義されている場合、audクレームの一部としてセカンダリ・オーディエンスも追加されます。アクセス・トークンの検証の一部として、aud配列のいずれかの値がリソース・サーバーに対して意味がある場合、サーバーでアクセスを許可する必要があります。

  4. 現在の時刻が有効期限(exp)クレームで表される時刻より前であることを検証します。

  5. スコープ・クレームの内容に基づいて操作を実行する権限がアクセス・トークンにあることを検証します。アクセス・トークンのスコープ・クレームは、スペース区切りの文字列のリストです。