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 *     <li>OAuth 2.0 (RFC 6749), section 3.1.
021 *     <li>OAuth 2.0 Multiple Response Type Encoding Practices 1.0.
022 *     <li>OAuth 2.0 Form Post Response Mode 1.0.
023 * </ul>
024 */
025public class AuthenticationResponseParser {
026
027
028        /**
029         * Parses an OpenID Connect authentication response.
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 response.
040         */
041        public static AuthenticationResponse parse(final URI redirectURI,
042                                                   final Map<String,String> params)
043                throws ParseException {
044
045                if (params.containsKey("error"))
046                        return AuthenticationErrorResponse.parse(redirectURI, params);
047                else
048                        return AuthenticationSuccessResponse.parse(redirectURI, params);
049        }
050
051
052        /**
053         * Parses an OpenID Connect authentication response.
054         *
055         * <p>Use a relative URI if the host, port and path details are not
056         * known:
057         *
058         * <pre>
059         * URI relUrl = new URI("https:///?code=Qcb0Orv1...&state=af0ifjsldkj");
060         * </pre>
061         *
062         * <p>Example URI:
063         *
064         * <pre>
065         * https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
066         * </pre>
067         *
068         * @param uri The URI to parse. Can be absolute or relative, with a
069         *            fragment or query string containing the authentication
070         *            response parameters. Must not be {@code null}.
071         *
072         * @return The OpenID Connect authentication success or error response.
073         *
074         * @throws ParseException If the redirection URI couldn't be parsed to
075         *                        an OpenID Connect authentication response.
076         */
077        public static AuthenticationResponse parse(final URI uri)
078                throws ParseException {
079
080                String paramString;
081                
082                if (uri.getRawQuery() != null) {
083
084                        paramString = uri.getRawQuery();
085
086                } else if (uri.getRawFragment() != null) {
087
088                        paramString = uri.getRawFragment();
089
090                } else {
091
092                        throw new ParseException("Missing authorization response parameters");
093                }
094                
095                Map<String,String> params = URLUtils.parseParameters(paramString);
096
097                if (params == null)
098                        throw new ParseException("Missing or invalid authorization response parameters");
099
100                return parse(URIUtils.getBaseURI(uri), params);
101        }
102
103
104        /**
105         * Parses an OpenID Connect authentication response.
106         *
107         * <p>Example HTTP response:
108         *
109         * <pre>
110         * HTTP/1.1 302 Found
111         * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
112         * </pre>
113         *
114         * @param httpResponse The HTTP response to parse. Must not be 
115         *                     {@code null}.
116         *
117         * @return The OpenID Connect authentication success or error response.
118         *
119         * @throws ParseException If the HTTP response couldn't be parsed to an 
120         *                        OpenID Connect authentication response.
121         */
122        public static AuthenticationResponse parse(final HTTPResponse httpResponse)
123                throws ParseException {
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}