トークン検証

トークンを検証する理由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トランザクションが成功するには、アイデンティティ・ドメインOAuth認可サーバーが、APIコールを認証するために使用するアクセス・トークンを発行する必要があります。アクセス・トークンでは、クライアント・アプリケーションに発行される認可を表し、保護されている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. スコープ・クレームの内容に基づいて操作を実行する権限がアクセス・トークンにあることを検証します。アクセス・トークンのスコープ・クレームは、スペース区切りの文字列のリストです。