Identity Token Validation

Why do we validate tokens? When your web application checks credentials directly, it verifies that the user name and password that are presented correspond to what you maintain. When using claims-based identity, you are outsourcing that job to an identity provider.

The responsibility shifts from verifying raw credentials to verifying that the requestor went through your preferred identity provider and successfully authenticated. The identity provider represents successful authentication by issuing a token. Before you can use the information or rely on it as an assertion that the user has authenticated, you must validate it.

OpenID Discovery Document

The OpenID Connect 1.0 protocol is a simple identity layer on top of the OAuth 2.0 protocol that requires the use of multiple endpoints for authenticating users and for requesting resources that include user information, tokens, and public keys. To help with discovering what these endpoints are that you need to use, OpenID Connect allows you to use a discovery document, which is a JSON document found at a well-known location. This discovery document contains key/value pairs that provide details about the OpenID Connect provider's configuration, including the URIs of the authorization, token, userinfo, and public keys endpoints. You can retrieve the discovery document for Oracle Identity Cloud Service's OpenID Connect service from: https://<tenant-base-url>/.well-known/openid-configuration.

See the Oracle Identity Cloud Service OpenID Discovery docs.

Validating Identity Tokens

An Identity (ID) Token is an integrity-secured, self-contained token (in JSON Web Token format) that contains claims about the end user. It represents an authenticated user's session. Therefore, the token must be validated before an application can trust the contents of the ID Token. For example, if a malicious attacker replayed a user's ID Token that they had captured earlier, the application should detect that the token has been replayed or was used after it had expired and deny the authentication.

The ID Token is defined in the OpenID Connect standard and is the primary extension that OpenID Connect makes to OAuth 2.0 to enable authentication. ID Tokens are sensitive and can be misused if intercepted. You must ensure that these tokens are handled securely by transmitting them only over HTTPS and only via POST data or within request headers. If you store them on your server, you must also store them securely.
  1. Verify that the value of the audience (aud) claim contains the application's client_id value. The aud (audience) claim may contain an array with more than one element. The ID Token must be rejected if the ID token doesn't list the client as a valid audience, or if it contains additional audiences that aren't trusted by the client.

  2. Verify that the current time is before the time represented by the expiry time (exp) claim.

  3. Verify that the ID Token is properly signed by the issuer. Oracle Identity Cloud Service-issued tokens are signed using one of the certificates found at the URI specified in the jwks_uri field of the discovery document.
    • Retrieve the tenant's public certificate from the SigningCert/jwk endpoint (for example,


      Since Oracle Identity Cloud Service changes its public keys infrequently, you can cache the public keys and, in the vast majority of cases, efficiently perform local validation. This requires retrieving and parsing certificates and making the appropriate crypto calls to check the signature:
    • Use any JWT libraries available to validate, for example, Connect2id's Nimbus JWT Library for Java. See JWT for a list of available libraries.


      In case of signature validation failure, to prevent constant re-fetches in case of attacks with bogus tokens, the re-fetching/re-caching of the public key should be based on a time interval, such as 60 minutes, so that re-fetches only happen every 60 minutes.


    package sample;
    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://tenant-base-url/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);
                // Process the token
                SecurityContext ctx = null; // optional context parameter, not required here
                JWTClaimsSet claimsSet = jwtProcessor.process(tokenValue, ctx);
                // Print out the token claims set
            } catch (Exception e) {
  4. Verify that the value of the Issuer Identifier (iss) claim exactly matches the value of the iss (issuer) claim: