PHP code example of ingenerator / oidc-token-verifier

1. Go to this page and download the library: Download ingenerator/oidc-token-verifier library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ingenerator / oidc-token-verifier example snippets


// Where the AUTHORIZATION header is `Bearer {token}`
use Google\Auth\Cache\SysVCacheItemPool;use Ingenerator\OIDCTokenVerifier\OIDCTokenVerifier;use Ingenerator\OIDCTokenVerifier\OpenIDDiscoveryCertificateProvider;use Ingenerator\OIDCTokenVerifier\TokenConstraints;use Ingenerator\OIDCTokenVerifier\TokenVerificationResult;use Psr\Log\NullLogger;use test\mock\Ingenerator\OIDCTokenVerifier\Cache\MockCacheItemPool;
[$bearer, $jwt] = explode(' ', $_SERVER['HTTP_AUTHORIZATION']);
$verifier = new OIDCTokenVerifier(
    new OpenIDDiscoveryCertificateProvider(
        new \GuzzleHttp\Client, 
        // Any psr-6 CacheItemPoolInterface implementation, used for caching issuer certificates
        new CacheItemPoolInterface,  
        new NullLogger // Any PSR logger
    ),
    // You *must* explicitly provide the issuer your application expects to receive tokens from.
    // The verifier will *only* request certificates from this issuer. Otherwise, any third party could set up an HTTP 
    // certificate endpoint and send you tokens signed by them.
    //
    // If your application may receive tokens from more than one issuer, you will need to (securely) identify the issuer
    // of a specific token and then create an appropriate verifier.
    // 
    'https://accounts.google.com'
);

// See below for details of the TokenConstraints argument
$result = $verifier->verify($jwt, TokenConstraints::signatureCheckOnly()); 

// You can either interrogate the result like this
if ( ! $result->isVerified()) {
    echo "NOT AUTHORISED\n";
    echo $result->getFailure()->getMessage()."\n";
} else {
    // The JWT payload is available from the result object
    echo "Authorised as ".$result->getPayload()->email."\n";
}

// Or if you'd prefer to throw an exception on failed auth this will:
// - Throw TokenVerificationFailedException if verification failed
// - Return the verified result if successful
$result = TokenVerificationResult::enforce($result);

$verifier->verify($jwt, new TokenConstraints([
    // The audience (`aud` claim) of the JWT must exactly match this value
    // Some google services use the URL that is being called. Others provide a custom value - an app/client ID, etc
    'audience_exact' => 'https://my.app.com/task-handler-url',
    
    // The audience (`aud` claim) of the JWT is a URL and the path (and querystring if any) must match this value
    // In some loadbalanced environments it's hard to detect the external protocol or hostname from an incoming
    // request - e.g. a request to https://my.app.loadbalancer may appear to PHP as being to http://app.cluster.local.
    // Although this can be worked round with custom headers (X_FORWARDED_PROTO etc) these introduce other risks and
    // ultimately couple the app implementation to architectural concerns. In many cases, it's enough to verify the
    // the resource the token was generated for (path and querystring) without caring about scheme and hostname. This
    // alone prevents using a stolen token to perform a different operation. Cross-environment / cross-site attacks
    // are instead protected by using different service accounts for each separate logical system so that e.g a token
    // generated for QA cannot ever authorise that operation in production regardless of the hostnames used.
    'audience_path_and_query' => 'http://appserver.internal/action?record_id=15',

    // The JWT must contain an `email` claim, and it must exactly match this value
    'email_exact' => '[email protected]',
    
    // The JWT must contain an `email` claim, and it must exactly match one of these values
    // Useful when you have a short list of service accounts that may be allowed to call your endpoint    
    'email_exact' => [
        '[email protected]',
        '[email protected]',
    ],
    
    // The JWT must contain an `email` claim, and it must match this regex
    // Useful when you want to e.g. authorize all service accounts in a particular domain - use with caution!
    'email_match' => '/@myproject.serviceaccount.test$/'  
]));

class MyTokenConstraints extends TokenConstraints {
    
    protected static function getAllMatchers(): array {
        $matchers = parent::getAllMatchers();
        // Constraint matchers are an array of {name} => boolean function indicating if the payload matches
        $matchers['user_role_contains'] = function (\stdClass $payload, string $expect) {
            // $payload is the decoded JWT
            // We check it has a custom claim ->user_roles as an array of roles
            return in_array($expect, $payload->user_roles ?? [], TRUE);       
        };
        return $matchers;    
    }
}

$verifier->verify($jwt, new MyTokenConstraints([
    'audience_exact'     => 'https://foo.bar/something',
    'user_role_contains' => 'administrator'
]));