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 com.nimbusds.jose.JOSEException; 022import com.nimbusds.jose.JWSAlgorithm; 023import com.nimbusds.jwt.SignedJWT; 024import com.nimbusds.oauth2.sdk.dpop.JWKThumbprintConfirmation; 025import com.nimbusds.oauth2.sdk.id.JWTID; 026import com.nimbusds.oauth2.sdk.util.singleuse.SingleUseChecker; 027import com.nimbusds.openid.connect.sdk.Nonce; 028import net.jcip.annotations.ThreadSafe; 029 030import java.net.URI; 031import java.util.Map; 032import java.util.Objects; 033import java.util.Set; 034 035 036/** 037 * DPoP proof JWT verifier for the OAuth 2.0 token endpoint of an authorisation 038 * server. 039 */ 040@ThreadSafe 041public class DPoPTokenRequestVerifier extends DPoPCommonVerifier { 042 043 044 /** 045 * The token endpoint URI. 046 */ 047 private final URI endpointURI; 048 049 050 /** 051 * Creates a new DPoP proof JWT verifier for the OAuth 2.0 token 052 * endpoint. 053 * 054 * @param acceptedJWSAlgs The accepted JWS algorithms. Must be 055 * supported and not {@code null}. 056 * @param endpointURI The token endpoint URI. Any query or 057 * fragment component will be stripped from 058 * it before performing the comparison. Must 059 * not be {@code null}. 060 * @param maxClockSkewSeconds The max acceptable clock skew for the 061 * "iat" (issued-at) claim checks, in 062 * seconds. Should be in the order of a few 063 * seconds. 064 * @param singleUseChecker The single use checker for the DPoP proof 065 * "jti" (JWT ID) claims, {@code null} if 066 * not specified. 067 */ 068 public DPoPTokenRequestVerifier(final Set<JWSAlgorithm> acceptedJWSAlgs, 069 final URI endpointURI, 070 final long maxClockSkewSeconds, 071 final SingleUseChecker<Map.Entry<DPoPIssuer, JWTID>> singleUseChecker) { 072 073 super(acceptedJWSAlgs, maxClockSkewSeconds, singleUseChecker); 074 this.endpointURI = Objects.requireNonNull(endpointURI); 075 } 076 077 078 /** 079 * Verifies the specified DPoP proof and returns the DPoP JWK SHA-256 080 * thumbprint confirmation. 081 * 082 * @param issuer Unique identifier for the DPoP proof issuer, typically 083 * as its client ID. Must not be {@code null}. 084 * @param proof The DPoP proof JWT. Must not be {@code null}. 085 * 086 * @return The DPoP JWK SHA-256 thumbprint confirmation. 087 * 088 * @throws InvalidDPoPProofException If the DPoP proof is invalid. 089 * @throws JOSEException If an internal JOSE exception is 090 * encountered. 091 */ 092 @Deprecated 093 public JWKThumbprintConfirmation verify(final DPoPIssuer issuer, final SignedJWT proof) 094 throws InvalidDPoPProofException, JOSEException { 095 096 return verify(issuer, proof, null); 097 } 098 099 100 /** 101 * Verifies the specified DPoP proof and returns the DPoP JWK SHA-256 102 * thumbprint confirmation. 103 * 104 * @param issuer Unique identifier for the DPoP proof issuer, typically 105 * as its client ID. Must not be {@code null}. 106 * @param proof The DPoP proof JWT. Must not be {@code null}. 107 * @param nonce The expected DPoP proof JWT nonce, {@code null} if 108 * none. 109 * 110 * @return The DPoP JWK SHA-256 thumbprint confirmation. 111 * 112 * @throws InvalidDPoPProofException If the DPoP proof is invalid. 113 * @throws JOSEException If an internal JOSE exception is 114 * encountered. 115 */ 116 public JWKThumbprintConfirmation verify(final DPoPIssuer issuer, final SignedJWT proof, final Nonce nonce) 117 throws InvalidDPoPProofException, JOSEException { 118 119 try { 120 super.verify("POST", endpointURI, issuer, proof, null, null, nonce); 121 } catch (AccessTokenValidationException e) { 122 throw new RuntimeException("Unexpected exception", e); 123 } 124 125 return new JWKThumbprintConfirmation(proof.getHeader().getJWK().computeThumbprint()); 126 } 127}