001package com.nimbusds.openid.connect.sdk;
002
003
004import java.net.URI;
005import java.util.Map;
006
007import com.nimbusds.oauth2.sdk.ParseException;
008import com.nimbusds.oauth2.sdk.http.HTTPResponse;
009import com.nimbusds.oauth2.sdk.util.URIUtils;
010import com.nimbusds.oauth2.sdk.util.URLUtils;
011
012
013/**
014 * Parser of OpenID Connect authentication response messages.
015 *
016 * <p>Related specifications:
017 *
018 * <ul>
019 *     <li>OpenID Connect Core 1.0, sections 3.1.2.5. and 3.1.2.6.
020 * </ul>
021 */
022public class AuthenticationResponseParser {
023
024
025        /**
026         * Parses an OpenID Connect authentication success or error response
027         * from the specified redirection URI and parameters.
028         *
029         * @param redirectURI The base redirection URI. Must not be
030         *                    {@code null}.
031         * @param params      The response parameters to parse. Must not be 
032         *                    {@code null}.
033         *
034         * @return The OpenID Connect authentication success or error response.
035         *
036         * @throws ParseException If the parameters couldn't be parsed to an
037         *                        OpenID Connect authentication success or
038         *                        error response.
039         */
040        public static AuthenticationResponse parse(final URI redirectURI,
041                                                   final Map<String,String> params)
042                throws ParseException {
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 URI uri)
072                throws ParseException {
073
074                String paramString;
075                
076                if (uri.getRawQuery() != null) {
077
078                        paramString = uri.getRawQuery();
079
080                } else if (uri.getRawFragment() != null) {
081
082                        paramString = uri.getRawFragment();
083
084                } else {
085
086                        throw new ParseException("Missing authorization response parameters");
087                }
088                
089                Map<String,String> params = URLUtils.parseParameters(paramString);
090
091                if (params == null)
092                        throw new ParseException("Missing or invalid authorization response parameters");
093
094                return parse(URIUtils.getBaseURI(uri), params);
095        }
096
097
098        /**
099         * Parses an OpenID Connect authentication success or error response
100         * from the specified HTTP response.
101         *
102         * <p>Example HTTP response:
103         *
104         * <pre>
105         * HTTP/1.1 302 Found
106         * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
107         * </pre>
108         *
109         * @param httpResponse The HTTP response to parse. Must not be 
110         *                     {@code null}.
111         *
112         * @return The OpenID Connect authentication success or error response.
113         *
114         * @throws ParseException If the HTTP response couldn't be parsed to an 
115         *                        OpenID Connect authentication success or
116         *                        error response.
117         */
118        public static AuthenticationResponse parse(final HTTPResponse httpResponse)
119                throws ParseException {
120
121                if (httpResponse.getStatusCode() != HTTPResponse.SC_FOUND)
122                        throw new ParseException("Unexpected HTTP status code, must be 302 (Found): " + 
123                                                 httpResponse.getStatusCode());
124                
125                URI location = httpResponse.getLocation();
126                
127                if (location == null)
128                        throw new ParseException("Missing redirection URI / HTTP Location header");
129
130                return parse(location);
131        }
132
133
134        /**
135         * Prevents public instantiation.
136         */
137        private AuthenticationResponseParser() { }
138}