All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nimbusds.oauth2.sdk.auth.verifier.ClientAuthenticationVerifier Maven / Gradle / Ivy

Go to download

OAuth 2.0 SDK with OpenID Connection extensions for developing client and server applications.

There is a newer version: 11.21
Show newest version
package com.nimbusds.oauth2.sdk.auth.verifier;


import java.security.PublicKey;
import java.util.List;
import java.util.Set;

import net.jcip.annotations.ThreadSafe;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory;
import com.nimbusds.jose.proc.JWSVerifierFactory;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.jwt.proc.BadJWTException;

import com.nimbusds.oauth2.sdk.auth.*;
import com.nimbusds.oauth2.sdk.id.Audience;


/**
 * Client authentication verifier.
 *
 * 

Related specifications: * *

    *
  • OAuth 2.0 (RFC 6749), sections 2.3.1 and 3.2.1. *
  • OpenID Connect Core 1.0, section 9. *
  • JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and * Authorization Grants (RFC 7523). *
*/ @ThreadSafe public class ClientAuthenticationVerifier { /** * The client credentials selector. */ private final ClientCredentialsSelector clientCredentialsSelector; /** * The JWT assertion claims set verifier. */ private final JWTAuthenticationClaimsSetVerifier claimsSetVerifier; /** * JWS verifier factory for private_key_jwt authentication. */ private final JWSVerifierFactory jwsVerifierFactory = new DefaultJWSVerifierFactory(); /** * Creates a new client authentication verifier. * * @param clientCredentialsSelector The client credentials selector. * Must not be {@code null}. * @param expectedAudience The permitted audience (aud) claim * values in JWT authentication * assertions. Must not be empty or * {@code null}. Should typically * contain the token endpoint URI and * for OpenID provider it may also * include the issuer URI. */ public ClientAuthenticationVerifier(final ClientCredentialsSelector clientCredentialsSelector, final Set expectedAudience) { claimsSetVerifier = new JWTAuthenticationClaimsSetVerifier(expectedAudience); if (clientCredentialsSelector == null) { throw new IllegalArgumentException("The client credentials selector must not be null"); } this.clientCredentialsSelector = clientCredentialsSelector; } /** * Returns the client credentials selector. * * @return The client credentials selector. */ public ClientCredentialsSelector getClientCredentialsSelector() { return clientCredentialsSelector; } /** * Returns the permitted audience values in JWT authentication * assertions. * * @return The permitted audience (aud) claim values. */ public Set getExpectedAudience() { return claimsSetVerifier.getExpectedAudience(); } /** * Verifies a client authentication request. * * @param clientAuth The client authentication. Must not be * {@code null}. * @param context Additional context to be passed to the client * credentials selector. May be {@code null}. * * @return {@code true} if the client was successfully authenticated, * {@code false} if the authentication failed due to an unknown * client, invalid credential or unsupported authentication * method. * * @throws JOSEException */ public boolean verify(final ClientAuthentication clientAuth, final Context context) throws JOSEException { if (clientAuth instanceof PlainClientSecret) { List secretCandidates = clientCredentialsSelector.selectClientSecrets( clientAuth.getClientID(), clientAuth.getMethod(), context); if (secretCandidates == null) { return false; // invalid client } PlainClientSecret plainAuth = (PlainClientSecret)clientAuth; for (Secret candidate: secretCandidates) { if (plainAuth.getClientSecret().equals(candidate)) { return true; // success } } return false; // invalid client } else if (clientAuth instanceof ClientSecretJWT) { ClientSecretJWT jwtAuth = (ClientSecretJWT) clientAuth; // Check claims first before calling backend try { claimsSetVerifier.verify(jwtAuth.getJWTAuthenticationClaimsSet().toJWTClaimsSet()); } catch (BadJWTException e) { return false; // invalid client } List secretCandidates = clientCredentialsSelector.selectClientSecrets( clientAuth.getClientID(), clientAuth.getMethod(), context); if (secretCandidates == null) { return false; // invalid client } SignedJWT assertion = jwtAuth.getClientAssertion(); for (Secret candidate : secretCandidates) { boolean valid = assertion.verify(new MACVerifier(candidate.getValueBytes())); if (valid) { return true; // success } } return false; // invalid client } else if (clientAuth instanceof PrivateKeyJWT) { PrivateKeyJWT jwtAuth = (PrivateKeyJWT)clientAuth; // Check claims first before calling backend try { claimsSetVerifier.verify(jwtAuth.getJWTAuthenticationClaimsSet().toJWTClaimsSet()); } catch (BadJWTException e) { return false; // invalid client } List keyCandidates = clientCredentialsSelector.selectPublicKeys( jwtAuth.getClientID(), jwtAuth.getMethod(), jwtAuth.getClientAssertion().getHeader(), context); if (keyCandidates == null) { return false; // invalid client } SignedJWT assertion = jwtAuth.getClientAssertion(); for (PublicKey candidate: keyCandidates) { if (candidate == null) { continue; // skip } JWSVerifier jwsVerifier = jwsVerifierFactory.createJWSVerifier( jwtAuth.getClientAssertion().getHeader(), candidate); boolean valid = assertion.verify(jwsVerifier); if (valid) { return true; // success } } return false; // invalid client } else { throw new RuntimeException("Unexpected client authentication: " + clientAuth.getMethod()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy