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.List;
023import java.util.Map;
024
025import com.nimbusds.oauth2.sdk.ParseException;
026import com.nimbusds.oauth2.sdk.http.HTTPResponse;
027import com.nimbusds.oauth2.sdk.util.URIUtils;
028import com.nimbusds.oauth2.sdk.util.URLUtils;
029
030
031/**
032 * Parser of OpenID Connect authentication response messages.
033 *
034 * <p>Related specifications:
035 *
036 * <ul>
037 *     <li>OpenID Connect Core 1.0, sections 3.1.2.5. and 3.1.2.6.
038 *     <li>OAuth 2.0 (RFC 6749), section 3.1.
039 *     <li>OAuth 2.0 Multiple Response Type Encoding Practices 1.0.
040 *     <li>OAuth 2.0 Form Post Response Mode 1.0.
041 * </ul>
042 */
043public class AuthenticationResponseParser {
044
045
046        /**
047         * Parses an OpenID Connect authentication response.
048         *
049         * @param redirectURI The base redirection URI. Must not be
050         *                    {@code null}.
051         * @param params      The response parameters to parse. Must not be 
052         *                    {@code null}.
053         *
054         * @return The OpenID Connect authentication success or error response.
055         *
056         * @throws ParseException If the parameters couldn't be parsed to an
057         *                        OpenID Connect authentication response.
058         */
059        public static AuthenticationResponse parse(final URI redirectURI,
060                                                   final Map<String,List<String>> params)
061                throws ParseException {
062
063                if (params.containsKey("error"))
064                        return AuthenticationErrorResponse.parse(redirectURI, params);
065                else
066                        return AuthenticationSuccessResponse.parse(redirectURI, params);
067        }
068
069
070        /**
071         * Parses an OpenID Connect authentication response.
072         *
073         * <p>Use a relative URI if the host, port and path details are not
074         * known:
075         *
076         * <pre>
077         * URI relUrl = new URI("https:///?code=Qcb0Orv1...&amp;state=af0ifjsldkj");
078         * </pre>
079         *
080         * <p>Example URI:
081         *
082         * <pre>
083         * https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
084         * </pre>
085         *
086         * @param uri The URI to parse. Can be absolute or relative, with a
087         *            fragment or query string containing the authentication
088         *            response parameters. Must not be {@code null}.
089         *
090         * @return The OpenID Connect authentication success or error response.
091         *
092         * @throws ParseException If the redirection URI couldn't be parsed to
093         *                        an OpenID Connect authentication response.
094         */
095        public static AuthenticationResponse parse(final URI uri)
096                throws ParseException {
097
098                String paramString;
099                
100                if (uri.getRawQuery() != null) {
101
102                        paramString = uri.getRawQuery();
103
104                } else if (uri.getRawFragment() != null) {
105
106                        paramString = uri.getRawFragment();
107
108                } else {
109
110                        throw new ParseException("Missing authorization response parameters");
111                }
112                
113                Map<String,List<String>> params = URLUtils.parseParameters(paramString);
114
115                if (params == null)
116                        throw new ParseException("Missing or invalid authorization response parameters");
117
118                return parse(URIUtils.getBaseURI(uri), params);
119        }
120
121
122        /**
123         * Parses an OpenID Connect authentication response.
124         *
125         * <p>Example HTTP response:
126         *
127         * <pre>
128         * HTTP/1.1 302 Found
129         * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
130         * </pre>
131         *
132         * @param httpResponse The HTTP response to parse. Must not be 
133         *                     {@code null}.
134         *
135         * @return The OpenID Connect authentication success or error response.
136         *
137         * @throws ParseException If the HTTP response couldn't be parsed to an 
138         *                        OpenID Connect authentication response.
139         */
140        public static AuthenticationResponse parse(final HTTPResponse httpResponse)
141                throws ParseException {
142
143                URI location = httpResponse.getLocation();
144                
145                if (location == null)
146                        throw new ParseException("Missing redirection URI / HTTP Location header");
147
148                return parse(location);
149        }
150
151
152        /**
153         * Prevents public instantiation.
154         */
155        private AuthenticationResponseParser() { }
156}