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.token.DPoPAccessToken;
027import com.nimbusds.oauth2.sdk.util.Receiver;
028import com.nimbusds.oauth2.sdk.util.singleuse.SingleUseChecker;
029import com.nimbusds.openid.connect.sdk.Nonce;
030import net.jcip.annotations.ThreadSafe;
031
032import java.net.URI;
033import java.util.Collections;
034import java.util.Map;
035import java.util.Objects;
036import java.util.Set;
037
038
039/**
040 * DPoP proof JWT verifier for a protected resource.
041 */
042@ThreadSafe
043public class DPoPProtectedResourceRequestVerifier extends DPoPCommonVerifier {
044        
045        
046        /**
047         * Creates a new DPoP proof JWT verifier for a protected resource.
048         *
049         * @param acceptedJWSAlgs     The accepted JWS algorithms. Must be
050         *                            supported and not {@code null}.
051         * @param maxClockSkewSeconds The maximum permitted DPoP proof "iat"
052         *                            clock skew, in seconds. A proof with
053         *                            "iat" in the future is accepted if it is
054         *                            within this skew tolerance. Intended to
055         *                            prevent rejections due to client and
056         *                            server system time differences.
057         * @param maxAgeSeconds       The maximum accepted DPoP proof "iat" age
058         *                            relative to the current system time, in
059         *                            seconds. Intended to limit replay by
060         *                            bounding how long a proof is valid after
061         *                            issue.
062         * @param singleUseChecker    The single use checker for the DPoP proof
063         *                            "jti" (JWT ID) claims, {@code null} if
064         *                            not specified.
065         */
066        public DPoPProtectedResourceRequestVerifier(final Set<JWSAlgorithm> acceptedJWSAlgs,
067                                                    final long maxClockSkewSeconds,
068                                                    final long maxAgeSeconds,
069                                                    final SingleUseChecker<DPoPProofUse> singleUseChecker) {
070                
071                super(acceptedJWSAlgs, maxClockSkewSeconds, maxAgeSeconds, singleUseChecker);
072        }
073
074
075        /**
076         * Creates a new DPoP proof JWT verifier for a protected resource.
077         *
078         * @param acceptedJWSAlgs     The accepted JWS algorithms. Must be
079         *                            supported and not {@code null}.
080         * @param maxClockSkewSeconds The maximum permitted DPoP proof "iat"
081         *                            clock skew, in seconds. A proof with
082         *                            "iat" in the future is accepted if it is
083         *                            within this skew tolerance. Intended to
084         *                            prevent rejections due to client and
085         *                            server system time differences.
086         * @param singleUseChecker    The single use checker for the DPoP proof
087         *                            "jti" (JWT ID) claims, {@code null} if
088         *                            not specified.
089         */
090        @Deprecated
091        public DPoPProtectedResourceRequestVerifier(final Set<JWSAlgorithm> acceptedJWSAlgs,
092                                                    final long maxClockSkewSeconds,
093                                                    final SingleUseChecker<Map.Entry<DPoPIssuer, JWTID>> singleUseChecker) {
094
095                super(acceptedJWSAlgs, maxClockSkewSeconds, singleUseChecker);
096        }
097        
098        
099        /**
100         * Verifies the specified DPoP proof and its access token and JWK
101         * SHA-256 thumbprint bindings.
102         *
103         * @param method      The HTTP request method (case-insensitive). Must
104         *                    not be {@code null}.
105         * @param uri         The HTTP URI. Any query or fragment component
106         *                    will be stripped from it before DPoP validation.
107         *                    Must not be {@code null}.
108         * @param issuer      Unique identifier for the DPoP proof issuer, such
109         *                    as its client ID. Must not be {@code null}.
110         * @param proof       The DPoP proof JWT, {@code null} if not received.
111         * @param accessToken The received and successfully validated DPoP
112         *                    access token. Must not be {@code null}.
113         * @param cnf         The JWK SHA-256 thumbprint confirmation for the
114         *                    DPoP access token. Must not be {@code null}.
115         *
116         * @throws InvalidDPoPProofException      If the DPoP proof is invalid
117         *                                        or missing.
118         * @throws InvalidDPoPNonceException      If the DPoP proof nonce is
119         *                                        invalid or missing.
120         * @throws AccessTokenValidationException If the DPoP access token
121         *                                        binding validation failed.
122         * @throws JOSEException                  If an internal JOSE exception
123         *                                        is encountered.
124         */
125        @Deprecated
126        public void verify(final String method,
127                           final URI uri,
128                           final DPoPIssuer issuer,
129                           final SignedJWT proof,
130                           final DPoPAccessToken accessToken,
131                           final JWKThumbprintConfirmation cnf)
132                throws
133                InvalidDPoPProofException,
134                AccessTokenValidationException,
135                JOSEException {
136                
137                verify(method, uri, issuer, proof, accessToken, cnf, (Set<Nonce>) null, null);
138        }
139        
140        
141        /**
142         * Verifies the specified DPoP proof and its access token and JWK
143         * SHA-256 thumbprint bindings.
144         *
145         * @param method      The HTTP request method (case-insensitive). Must
146         *                    not be {@code null}.
147         * @param uri         The HTTP URI. Any query or fragment component
148         *                    will be stripped from it before DPoP validation.
149         *                    Must not be {@code null}.
150         * @param issuer      Unique identifier for the DPoP proof issuer, such
151         *                    as its client ID. Must not be {@code null}.
152         * @param proof       The DPoP proof JWT, {@code null} if not received.
153         * @param accessToken The received and successfully validated DPoP
154         *                    access token. Must not be {@code null}.
155         * @param cnf         The JWK SHA-256 thumbprint confirmation for the
156         *                    DPoP access token. Must not be {@code null}.
157         * @param nonce       The accepted DPoP proof JWT nonce, {@code null}
158         *                    if none is expected.
159         *
160         * @throws InvalidDPoPProofException      If the DPoP proof is invalid
161         *                                        or missing.
162         * @throws InvalidDPoPNonceException      If the DPoP proof nonce is
163         *                                        invalid or missing.
164         * @throws AccessTokenValidationException If the DPoP access token
165         *                                        binding validation failed.
166         * @throws JOSEException                  If an internal JOSE exception
167         *                                        is encountered.
168         */
169        public void verify(final String method,
170                           final URI uri,
171                           final DPoPIssuer issuer,
172                           final SignedJWT proof,
173                           final DPoPAccessToken accessToken,
174                           final JWKThumbprintConfirmation cnf,
175                           final Nonce nonce)
176                throws
177                InvalidDPoPProofException,
178                AccessTokenValidationException,
179                JOSEException {
180                
181                verify(method, uri, issuer, proof, accessToken, cnf, nonce != null ? Collections.singleton(nonce) : null, null);
182        }
183
184
185        /**
186         * Verifies the specified DPoP proof and its access token and JWK
187         * SHA-256 thumbprint bindings.
188         *
189         * @param method      The HTTP request method (case-insensitive). Must
190         *                    not be {@code null}.
191         * @param uri         The HTTP URI. Any query or fragment component
192         *                    will be stripped from it before DPoP validation.
193         *                    Must not be {@code null}.
194         * @param issuer      Unique identifier for the DPoP proof issuer, such
195         *                    as its client ID. Must not be {@code null}.
196         * @param proof       The DPoP proof JWT, {@code null} if not received.
197         * @param accessToken The received and successfully validated DPoP
198         *                    access token. Must not be {@code null}.
199         * @param cnf         The JWK SHA-256 thumbprint confirmation for the
200         *                    DPoP access token. Must not be {@code null}.
201         * @param nonces      The accepted DPoP proof JWT nonce values,
202         *                    {@code null} if none are is expected.
203         * @param ctxReceiver To access the DPoP proof JWT claims set,
204         *                    {@code null} if not required.
205         *
206         * @throws InvalidDPoPProofException      If the DPoP proof is invalid
207         *                                        or missing.
208         * @throws InvalidDPoPNonceException      If the DPoP proof nonce is
209         *                                        invalid or missing.
210         * @throws AccessTokenValidationException If the DPoP access token
211         *                                        binding validation failed.
212         * @throws JOSEException                  If an internal JOSE exception
213         *                                        is encountered.
214         */
215        public void verify(final String method,
216                           final URI uri,
217                           final DPoPIssuer issuer,
218                           final SignedJWT proof,
219                           final DPoPAccessToken accessToken,
220                           final JWKThumbprintConfirmation cnf,
221                           final Set<Nonce> nonces,
222                           final Receiver<DPoPProofContext> ctxReceiver)
223                throws
224                InvalidDPoPProofException,
225                AccessTokenValidationException,
226                JOSEException {
227
228                if (proof == null) {
229                        throw new InvalidDPoPProofException("Missing required DPoP proof");
230                }
231
232                Objects.requireNonNull(accessToken);
233                Objects.requireNonNull(cnf);
234                super.verify(method, uri, issuer, proof, accessToken, cnf, nonces, ctxReceiver);
235        }
236}