001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk;
019
020
021import java.net.URI;
022import java.util.Map;
023
024import com.nimbusds.oauth2.sdk.ParseException;
025import com.nimbusds.oauth2.sdk.http.HTTPResponse;
026import com.nimbusds.oauth2.sdk.util.URIUtils;
027import com.nimbusds.oauth2.sdk.util.URLUtils;
028
029
030/**
031 * Parser of OpenID Connect authentication response messages.
032 *
033 * <p>Related specifications:
034 *
035 * <ul>
036 *     <li>OpenID Connect Core 1.0, sections 3.1.2.5. and 3.1.2.6.
037 *     <li>OAuth 2.0 (RFC 6749), section 3.1.
038 *     <li>OAuth 2.0 Multiple Response Type Encoding Practices 1.0.
039 *     <li>OAuth 2.0 Form Post Response Mode 1.0.
040 * </ul>
041 */
042public class AuthenticationResponseParser {
043
044
045        /**
046         * Parses an OpenID Connect authentication response.
047         *
048         * @param redirectURI The base redirection URI. Must not be
049         *                    {@code null}.
050         * @param params      The response parameters to parse. Must not be 
051         *                    {@code null}.
052         *
053         * @return The OpenID Connect authentication success or error response.
054         *
055         * @throws ParseException If the parameters couldn't be parsed to an
056         *                        OpenID Connect authentication response.
057         */
058        public static AuthenticationResponse parse(final URI redirectURI,
059                                                   final Map<String,String> params)
060                throws ParseException {
061
062                if (params.containsKey("error"))
063                        return AuthenticationErrorResponse.parse(redirectURI, params);
064                else
065                        return AuthenticationSuccessResponse.parse(redirectURI, params);
066        }
067
068
069        /**
070         * Parses an OpenID Connect authentication response.
071         *
072         * <p>Use a relative URI if the host, port and path details are not
073         * known:
074         *
075         * <pre>
076         * URI relUrl = new URI("https:///?code=Qcb0Orv1...&state=af0ifjsldkj");
077         * </pre>
078         *
079         * <p>Example URI:
080         *
081         * <pre>
082         * https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
083         * </pre>
084         *
085         * @param uri The URI to parse. Can be absolute or relative, with a
086         *            fragment or query string containing the authentication
087         *            response parameters. Must not be {@code null}.
088         *
089         * @return The OpenID Connect authentication success or error response.
090         *
091         * @throws ParseException If the redirection URI couldn't be parsed to
092         *                        an OpenID Connect authentication response.
093         */
094        public static AuthenticationResponse parse(final URI uri)
095                throws ParseException {
096
097                String paramString;
098                
099                if (uri.getRawQuery() != null) {
100
101                        paramString = uri.getRawQuery();
102
103                } else if (uri.getRawFragment() != null) {
104
105                        paramString = uri.getRawFragment();
106
107                } else {
108
109                        throw new ParseException("Missing authorization response parameters");
110                }
111                
112                Map<String,String> params = URLUtils.parseParameters(paramString);
113
114                if (params == null)
115                        throw new ParseException("Missing or invalid authorization response parameters");
116
117                return parse(URIUtils.getBaseURI(uri), params);
118        }
119
120
121        /**
122         * Parses an OpenID Connect authentication response.
123         *
124         * <p>Example HTTP response:
125         *
126         * <pre>
127         * HTTP/1.1 302 Found
128         * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
129         * </pre>
130         *
131         * @param httpResponse The HTTP response to parse. Must not be 
132         *                     {@code null}.
133         *
134         * @return The OpenID Connect authentication success or error response.
135         *
136         * @throws ParseException If the HTTP response couldn't be parsed to an 
137         *                        OpenID Connect authentication response.
138         */
139        public static AuthenticationResponse parse(final HTTPResponse httpResponse)
140                throws ParseException {
141
142                URI location = httpResponse.getLocation();
143                
144                if (location == null)
145                        throw new ParseException("Missing redirection URI / HTTP Location header");
146
147                return parse(location);
148        }
149
150
151        /**
152         * Prevents public instantiation.
153         */
154        private AuthenticationResponseParser() { }
155}