001package com.nimbusds.openid.connect.provider.spi.par; 002 003 004import net.jcip.annotations.ThreadSafe; 005 006import com.nimbusds.oauth2.sdk.AuthorizationRequest; 007import com.nimbusds.oauth2.sdk.GeneralException; 008import com.nimbusds.openid.connect.provider.spi.Lifecycle; 009 010 011/** 012 * Service Provider Interface (SPI) for performing additional validation of 013 * Pushed Authorisation Requests (PAR). 014 * 015 * <p>The {@link #validatePushedAuthorizationRequest} method will be called 016 * after the Connect2id server has performed standard validation of the OAuth 017 * 2.0 authorisation / OpenID authentication request, such as such as checking 018 * the {@code client_id} and ensuring the client is authorised to use the OAuth 019 * 2.0 grant. JWT-secured authorisation requests (JAR) will be unwrapped / 020 * resolved before that. 021 * 022 * <p>The validated request can be returned modified. Modifications should be 023 * limited to optional parameters. Parameters such as {@code client_id}, 024 * {@code response_type}, {@code redirect_uri} and {@code state} must not be 025 * modified. 026 * 027 * <p>The {@link #validatePushedAuthorizationRequest} method can reject the 028 * request by throwing an {@link InvalidPushedAuthorizationRequestException} 029 * with an appropriate HTTP status code and error code. The exception message 030 * will be logged and not output to the client. 031 * 032 * <p>Example: 033 * 034 * <pre> 035 * throw new InvalidPARException("Scope not accepted scope", // will be logged 036 * OAuth2Error.INVALID_SCOPE 037 * .setHTTPStatusCode(400) 038 * .setDescription("Scope not accepted: some_scope")); 039 * </pre> 040 * 041 * The resulting HTTP response: 042 * 043 * <pre> 044 * HTTP/1.1 400 Bad Request 045 * Content-Type: application/json;charset=UTF-8 046 * Cache-Control: no-store 047 * Pragma: no-cache 048 * 049 * { 050 * "error" : "invalid_scope", 051 * "error_description" : "Scope not accepted: some_scope" 052 * } 053 * </pre> 054 * 055 * <p>Implementations must be thread-safe. 056 */ 057@ThreadSafe 058public interface PARValidator extends Lifecycle { 059 060 061 /** 062 * Validates the specified OAuth 2.0 authorisation / OpenID 063 * authentication request. 064 * 065 * <p>Deprecated, use {@link #validatePushedAuthorizationRequest} 066 * instead. 067 * 068 * @param authzRequest The request to perform additional validation on. 069 * Can be cast to 070 * {@link com.nimbusds.openid.connect.sdk.AuthenticationRequest} 071 * for an instance of an OpenID authentication 072 * request. 073 * Not {@code null}. 074 * @param validatorCtx The PAR validator context. Not {@code null}. 075 * 076 * @throws GeneralException If the request is rejected. Should include 077 * an appropriate HTTP status and error code. 078 */ 079 @Deprecated 080 default void validate(final AuthorizationRequest authzRequest, final ValidatorContext validatorCtx) 081 throws GeneralException { 082 083 try { 084 validatePushedAuthorizationRequest(authzRequest, validatorCtx); 085 } catch (InvalidPushedAuthorizationRequestException e) { 086 throw new GeneralException(e.getMessage(), e.getErrorObject()); 087 } 088 } 089 090 091 /** 092 * Validates the specified OAuth 2.0 authorisation / OpenID 093 * authentication request. 094 * 095 * @param authzRequest The request to perform additional validation on. 096 * Can be cast to 097 * {@link com.nimbusds.openid.connect.sdk.AuthenticationRequest} 098 * for an instance of an OpenID authentication 099 * request. 100 * Not {@code null}. 101 * @param validatorCtx The PAR validator context. Not {@code null}. 102 * 103 * @return The validated OAuth 2.0 authorisation / OpenID 104 * authentication request. It may be modified. Must not be 105 * {@code null}. 106 * 107 * @throws InvalidPushedAuthorizationRequestException If the request is 108 * rejected. 109 */ 110 default AuthorizationRequest validatePushedAuthorizationRequest(final AuthorizationRequest authzRequest, 111 final ValidatorContext validatorCtx) 112 throws InvalidPushedAuthorizationRequestException { 113 114 try { 115 validate(authzRequest, validatorCtx); 116 } catch (GeneralException e) { 117 throw new InvalidPushedAuthorizationRequestException(e.getMessage(), e.getErrorObject()); 118 } 119 return authzRequest; 120 } 121}