001package com.nimbusds.openid.connect.sdk; 002 003 004import java.net.URI; 005import java.net.URISyntaxException; 006import java.net.URL; 007import java.util.Map; 008 009import com.nimbusds.oauth2.sdk.ParseException; 010import com.nimbusds.oauth2.sdk.http.HTTPResponse; 011import com.nimbusds.oauth2.sdk.util.URIUtils; 012import com.nimbusds.oauth2.sdk.util.URLUtils; 013 014 015/** 016 * Parser of OpenID Connect authentication response messages. 017 * 018 * <p>Related specifications: 019 * 020 * <ul> 021 * <li>OpenID Connect Core 1.0, sections 3.1.2.5. and 3.1.2.6. 022 * </ul> 023 */ 024public class AuthenticationResponseParser { 025 026 027 /** 028 * Parses an OpenID Connect authentication success or error response 029 * from the specified redirection URI and parameters. 030 * 031 * @param redirectURI The base redirection URI. Must not be 032 * {@code null}. 033 * @param params The response parameters to parse. Must not be 034 * {@code null}. 035 * 036 * @return The OpenID Connect authentication success or error response. 037 * 038 * @throws ParseException If the parameters couldn't be parsed to an 039 * OpenID Connect authentication success or 040 * error response. 041 */ 042 public static AuthenticationResponse parse(final URI redirectURI, 043 final Map<String,String> params) 044 throws ParseException { 045 046 if (params.containsKey("error")) 047 return AuthenticationErrorResponse.parse(redirectURI, params); 048 else 049 return AuthenticationSuccessResponse.parse(redirectURI, params); 050 } 051 052 053 /** 054 * Parses an OpenID Connect authentication success or error response 055 * from the specified URI. 056 * 057 * <p>Example URI: 058 * 059 * <pre> 060 * https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz 061 * </pre> 062 * 063 * @param uri The URI to parse. Can be absolute or relative, with a 064 * fragment or query string containing the authentication 065 * response parameters. Must not be {@code null}. 066 * 067 * @return The OpenID Connect authentication success or error response. 068 * 069 * @throws ParseException If the redirection URI couldn't be parsed to 070 * an OpenID Connect authentication success or 071 * error response. 072 */ 073 public static AuthenticationResponse parse(final URI uri) 074 throws ParseException { 075 076 String paramString; 077 078 if (uri.getRawQuery() != null) { 079 080 paramString = uri.getRawQuery(); 081 082 } else if (uri.getRawFragment() != null) { 083 084 paramString = uri.getRawFragment(); 085 086 } else { 087 088 throw new ParseException("Missing authorization response parameters"); 089 } 090 091 Map<String,String> params = URLUtils.parseParameters(paramString); 092 093 if (params == null) 094 throw new ParseException("Missing or invalid authorization response parameters"); 095 096 return parse(URIUtils.getBaseURI(uri), params); 097 } 098 099 100 /** 101 * Parses an OpenID Connect authentication success or error response 102 * from the specified HTTP response. 103 * 104 * <p>Example HTTP response: 105 * 106 * <pre> 107 * HTTP/1.1 302 Found 108 * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz 109 * </pre> 110 * 111 * @param httpResponse The HTTP response to parse. Must not be 112 * {@code null}. 113 * 114 * @return The OpenID Connect authentication success or error response. 115 * 116 * @throws ParseException If the HTTP response couldn't be parsed to an 117 * OpenID Connect authentication success or 118 * error response. 119 */ 120 public static AuthenticationResponse parse(final HTTPResponse httpResponse) 121 throws ParseException { 122 123 if (httpResponse.getStatusCode() != HTTPResponse.SC_FOUND) 124 throw new ParseException("Unexpected HTTP status code, must be 302 (Found): " + 125 httpResponse.getStatusCode()); 126 127 URL location = httpResponse.getLocation(); 128 129 if (location == null) 130 throw new ParseException("Missing redirection URI / HTTP Location header"); 131 132 try { 133 return parse(location.toURI()); 134 135 } catch (URISyntaxException e) { 136 137 throw new ParseException(e.getMessage(), e); 138 } 139 } 140 141 142 /** 143 * Prevents public instantiation. 144 */ 145 private AuthenticationResponseParser() { } 146}