001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2021, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.dpop.verifiers; 019 020 021import java.net.URI; 022import java.util.Map; 023import java.util.Set; 024 025import net.jcip.annotations.ThreadSafe; 026 027import com.nimbusds.jose.JOSEException; 028import com.nimbusds.jose.JWSAlgorithm; 029import com.nimbusds.jwt.SignedJWT; 030import com.nimbusds.oauth2.sdk.dpop.JWKThumbprintConfirmation; 031import com.nimbusds.oauth2.sdk.id.JWTID; 032import com.nimbusds.oauth2.sdk.util.singleuse.SingleUseChecker; 033 034 035/** 036 * DPoP proof JWT verifier for the OAuth 2.0 token endpoint of an authorisation 037 * server. 038 */ 039@ThreadSafe 040public class DPoPTokenRequestVerifier extends DPoPCommonVerifier { 041 042 043 /** 044 * The token endpoint URI. 045 */ 046 private final URI endpointURI; 047 048 049 /** 050 * Creates a new DPoP proof JWT verifier for the OAuth 2.0 token 051 * endpoint. 052 * 053 * @param acceptedJWSAlgs The accepted JWS algorithms. Must be 054 * supported and not {@code null}. 055 * @param endpointURI The token endpoint URI. Any query or 056 * fragment component will be stripped from 057 * it before performing the comparison. Must 058 * not be {@code null}. 059 * @param maxClockSkewSeconds The max acceptable clock skew for the 060 * "iat" (issued-at) claim checks, in 061 * seconds. Should be in the order of a few 062 * seconds. 063 * @param singleUseChecker The single use checker for the DPoP proof 064 * "jti" (JWT ID) claims, {@code null} if 065 * not specified. 066 */ 067 public DPoPTokenRequestVerifier(final Set<JWSAlgorithm> acceptedJWSAlgs, 068 final URI endpointURI, 069 final long maxClockSkewSeconds, 070 final SingleUseChecker<Map.Entry<DPoPIssuer, JWTID>> singleUseChecker) { 071 072 super(acceptedJWSAlgs, maxClockSkewSeconds, singleUseChecker); 073 074 if (endpointURI == null) { 075 throw new IllegalArgumentException("The token endpoint URI must not be null"); 076 } 077 this.endpointURI = endpointURI; 078 } 079 080 081 /** 082 * Verifies the specified DPoP proof and returns the DPoP JWK SHA-256 083 * thumbprint confirmation. 084 * 085 * @param issuer Unique identifier for the DPoP proof issuer, typically 086 * as its client ID. Must not be {@code null}. 087 * @param proof The DPoP proof JWT. Must not be {@code null}. 088 * 089 * @return The DPoP JWK SHA-256 thumbprint confirmation. 090 * 091 * @throws InvalidDPoPProofException If the DPoP proof is invalid. 092 * @throws JOSEException If an internal JOSE exception is 093 * encountered. 094 */ 095 public JWKThumbprintConfirmation verify(final DPoPIssuer issuer, final SignedJWT proof) 096 throws InvalidDPoPProofException, JOSEException { 097 098 try { 099 super.verify("POST", endpointURI, issuer, proof, null, null); 100 } catch (AccessTokenValidationException e) { 101 throw new RuntimeException("Unexpected exception", e); 102 } 103 104 return new JWKThumbprintConfirmation(proof.getHeader().getJWK().computeThumbprint()); 105 } 106}