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