56         MultivaluedMap<String, String> params = context.getHttpRequest().getDecodedFormParameters();
    58         String clientAssertionType = params.getFirst(OAuth2Constants.CLIENT_ASSERTION_TYPE);
    59         String clientAssertion = params.getFirst(OAuth2Constants.CLIENT_ASSERTION);
    61         if (clientAssertionType == null) {
    62             Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), 
"invalid_client", 
"Parameter client_assertion_type is missing");
    63             context.challenge(challengeResponse);
    67         if (!clientAssertionType.equals(OAuth2Constants.CLIENT_ASSERTION_TYPE_JWT)) {
    68             Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), 
"invalid_client", 
"Parameter client_assertion_type has value '"    69                     + clientAssertionType + 
"' but expected is '" + OAuth2Constants.CLIENT_ASSERTION_TYPE_JWT + 
"'");
    70             context.challenge(challengeResponse);
    74         if (clientAssertion == null) {
    75             Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), 
"invalid_client", 
"client_assertion parameter missing");
    76             context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS, challengeResponse);
    81             JWSInput jws = 
new JWSInput(clientAssertion);
    82             JsonWebToken token = jws.readJsonContent(JsonWebToken.class);
    84             RealmModel realm = context.getRealm();
    85             String clientId = token.getSubject();
    86             if (clientId == null) {
    87                 throw new RuntimeException(
"Can't identify client. Issuer missing on JWT token");
    90             context.getEvent().client(clientId);
    91             ClientModel client = realm.getClientByClientId(clientId);
    93                 context.failure(AuthenticationFlowError.CLIENT_NOT_FOUND, null);
    96                 context.setClient(client);
    99             if (!client.isEnabled()) {
   100                 context.failure(AuthenticationFlowError.CLIENT_DISABLED, null);
   104             String clientSecretString = client.getSecret();
   105             if (clientSecretString == null) {
   106                 context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS, null);
   114             SecretKey clientSecret = 
new SecretKeySpec(clientSecretString.getBytes(
"UTF-8"), 
"HmacSHA256");
   116             boolean signatureValid;
   118                 signatureValid = HMACProvider.verify(jws, clientSecret);
   119             } 
catch (RuntimeException e) {
   120                 Throwable cause = e.getCause() != null ? e.getCause() : e;
   121                 throw new RuntimeException(
"Signature on JWT token by client secret failed validation", cause);
   123             if (!signatureValid) {
   124                 throw new RuntimeException(
"Signature on JWT token by client secret  failed validation");
   130             String issuerUrl = Urls.realmIssuer(context.getUriInfo().getBaseUri(), realm.getName());
   131             String tokenUrl = OIDCLoginProtocolService.tokenUrl(context.getUriInfo().getBaseUriBuilder()).build(realm.getName()).toString();
   132             if (!token.hasAudience(issuerUrl) && !token.hasAudience(tokenUrl)) {
   133                 throw new RuntimeException(
"Token audience doesn't match domain. Realm issuer is '" + issuerUrl + 
"' but audience from token is '" + Arrays.asList(token.getAudience()).toString() + 
"'");
   136             if (!token.isActive()) {
   137                 throw new RuntimeException(
"Token is not active");
   141             if (token.getExpiration() == 0 && token.getIssuedAt() + 10 < Time.currentTime()) {
   142                 throw new RuntimeException(
"Token is not active");
   146         } 
catch (Exception e) {
   147             ServicesLogger.LOGGER.errorValidatingAssertion(e);
   148             Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), 
"unauthorized_client", 
"Client authentication with client secret signed JWT failed: " + e.getMessage());
   149             context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS, challengeResponse);