001package com.nimbusds.openid.connect.sdk; 002 003 004import java.net.URL; 005import java.util.Collections; 006import java.util.HashSet; 007import java.util.Map; 008import java.util.Set; 009 010import net.jcip.annotations.Immutable; 011 012import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse; 013import com.nimbusds.oauth2.sdk.ErrorObject; 014import com.nimbusds.oauth2.sdk.ParseException; 015import com.nimbusds.oauth2.sdk.ResponseType; 016import com.nimbusds.oauth2.sdk.id.State; 017import com.nimbusds.oauth2.sdk.http.HTTPResponse; 018 019 020/** 021 * OpenID Connect authorisation error response. This class is immutable. 022 * 023 * <p>Standard errors: 024 * 025 * <ul> 026 * <li>OAuth 2.0 authorisation errors: 027 * <ul> 028 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_REQUEST} 029 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#UNAUTHORIZED_CLIENT} 030 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#ACCESS_DENIED} 031 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#UNSUPPORTED_RESPONSE_TYPE} 032 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_SCOPE} 033 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#SERVER_ERROR} 034 * <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#TEMPORARILY_UNAVAILABLE} 035 * </ul> 036 * <li>OpenID Connect specific errors: 037 * <ul> 038 * <li>{@link OIDCError#INTERACTION_REQUIRED} 039 * <li>{@link OIDCError#LOGIN_REQUIRED} 040 * <li>{@link OIDCError#SESSION_SELECTION_REQUIRED} 041 * <li>{@link OIDCError#CONSENT_REQUIRED} 042 * <li>{@link OIDCError#INVALID_REQUEST_URI} 043 * <li>{@link OIDCError#INVALID_REQUEST_OBJECT} 044 * <li>{@link OIDCError#REGISTRATION_NOT_SUPPORTED} 045 * <li>{@link OIDCError#REQUEST_NOT_SUPPORTED} 046 * <li>{@link OIDCError#REQUEST_URI_NOT_SUPPORTED} 047 * </ul> 048 * </li> 049 * </ul> 050 * 051 * <p>Example HTTP response: 052 * 053 * <pre> 054 * HTTP/1.1 302 Found 055 * Location: https://client.example.org/cb? 056 * error=invalid_request 057 * &error_description=the%20request%20is%20not%20valid%20or%20malformed 058 * &state=af0ifjsldkj 059 * </pre> 060 * 061 * <p>Related specifications: 062 * 063 * <ul> 064 * <li>OpenID Connect Messages 1.0, section 2.1.3. 065 * <li>OpenID Connect Standard 1.0, section 2.3.5.2. 066 * </ul> 067 * 068 * @author Vladimir Dzhuvinov 069 */ 070@Immutable 071public class OIDCAuthorizationErrorResponse 072 extends AuthorizationErrorResponse 073 implements OIDCAuthorizationResponse { 074 075 076 /** 077 * The standard errors for an OpenID Connect Authorisation error 078 * response. 079 */ 080 private static Set<ErrorObject> stdErrors = new HashSet<ErrorObject>(); 081 082 083 static { 084 stdErrors.addAll(AuthorizationErrorResponse.getStandardErrors()); 085 086 stdErrors.add(OIDCError.INTERACTION_REQUIRED); 087 stdErrors.add(OIDCError.LOGIN_REQUIRED); 088 stdErrors.add(OIDCError.SESSION_SELECTION_REQUIRED); 089 stdErrors.add(OIDCError.CONSENT_REQUIRED); 090 stdErrors.add(OIDCError.INVALID_REQUEST_URI); 091 stdErrors.add(OIDCError.INVALID_REQUEST_OBJECT); 092 stdErrors.add(OIDCError.REGISTRATION_NOT_SUPPORTED); 093 stdErrors.add(OIDCError.REQUEST_NOT_SUPPORTED); 094 stdErrors.add(OIDCError.REQUEST_URI_NOT_SUPPORTED); 095 } 096 097 098 /** 099 * Gets the standard errors for an OpenID Connect Authorisation error 100 * response. 101 * 102 * @return The standard errors, as a read-only set. 103 */ 104 public static Set<ErrorObject> getStandardErrors() { 105 106 return Collections.unmodifiableSet(stdErrors); 107 } 108 109 110 /** 111 * Creates a new OpenID Connect authorisation error response. 112 * 113 * @param redirectURI The base redirect URI. Must not be {@code null}. 114 * @param error The error. Should match one of the 115 * {@link #getStandardErrors standard errors} for an 116 * OpenID Connect authorisation error response. Must 117 * not be {@code null}. 118 * @param rt The response type, used to determine the redirect 119 * URI composition. If unknown {@code null}. 120 * @param state The state, {@code null} if not requested. 121 */ 122 public OIDCAuthorizationErrorResponse(final URL redirectURI, 123 final ErrorObject error, 124 final ResponseType rt, 125 final State state) { 126 127 super(redirectURI, error, rt, state); 128 } 129 130 131 /** 132 * Parses an OpenID Connect authorisation error response from the 133 * specified redirect URI and parameters. 134 * 135 * @param redirectURI The base redirect URI. Must not be {@code null}. 136 * @param params The response parameters to parse. Must not be 137 * {@code null}. 138 * 139 * @return The OpenID Connect authorisation error response. 140 * 141 * @throws ParseException If the parameters couldn't be parsed to an 142 * OpenID Connect authorisation error response. 143 */ 144 public static OIDCAuthorizationErrorResponse parse(final URL redirectURI, 145 final Map<String,String> params) 146 throws ParseException { 147 148 AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(redirectURI, params); 149 150 return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(), 151 resp.getErrorObject(), 152 resp.getResponseType(), 153 resp.getState()); 154 } 155 156 157 /** 158 * Parses an OpenID Connect authorisation error response from the 159 * specified URI. 160 * 161 * <p>Example URI: 162 * 163 * <pre> 164 * https://client.example.com/cb? 165 * error=invalid_request 166 * &error_description=the%20request%20is%20not%20valid%20or%20malformed 167 * &state=af0ifjsldkj 168 * </pre> 169 * 170 * @param uri The URI to parse. Can be absolute or relative. Must not 171 * be {@code null}. 172 * 173 * @return The OpenID Connect authorisation error response. 174 * 175 * @throws ParseException If the URI couldn't be parsed to an OpenID 176 * Connect authorisation error response. 177 */ 178 public static OIDCAuthorizationErrorResponse parse(final URL uri) 179 throws ParseException { 180 181 AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(uri); 182 183 return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(), 184 resp.getErrorObject(), 185 resp.getResponseType(), 186 resp.getState()); 187 } 188 189 190 /** 191 * Parses an OpenID Connect authorisation error response from the 192 * specified HTTP response. 193 * 194 * <p>Example HTTP response: 195 * 196 * <pre> 197 * HTTP/1.1 302 Found 198 * Location: https://client.example.com/cb? 199 * error=invalid_request 200 * &error_description=the%20request%20is%20not%20valid%20or%20malformed 201 * &state=af0ifjsldkj 202 * </pre> 203 * 204 * @param httpResponse The HTTP response to parse. Must not be 205 * {@code null}. 206 * 207 * @return The OpenID Connect authorisation error response. 208 * 209 * @throws ParseException If the HTTP response couldn't be parsed to an 210 * OpenID Connect authorisation error response. 211 */ 212 public static OIDCAuthorizationErrorResponse parse(final HTTPResponse httpResponse) 213 throws ParseException { 214 215 AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(httpResponse); 216 217 return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(), 218 resp.getErrorObject(), 219 resp.getResponseType(), 220 resp.getState()); 221 } 222}