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;
022
023import net.jcip.annotations.Immutable;
024
025import com.nimbusds.common.contenttype.ContentType;
026import com.nimbusds.oauth2.sdk.ParseException;
027import com.nimbusds.oauth2.sdk.ProtectedResourceRequest;
028import com.nimbusds.oauth2.sdk.SerializeException;
029import com.nimbusds.oauth2.sdk.http.HTTPRequest;
030import com.nimbusds.oauth2.sdk.token.AccessToken;
031
032
033/**
034 * UserInfo request. Used to retrieve the consented claims about the end-user.
035 *
036 * <p>Example HTTP GET request with a Bearer token:
037 *
038 * <pre>
039 * GET /userinfo HTTP/1.1
040 * Host: server.example.com
041 * Authorization: Bearer Eabeeduphee3aiviehahreacaoNg2thu
042 * </pre>
043 *
044 * <p>Example HTTP GET request with a DPoP token and proof:
045 *
046 * <pre>
047 * GET /userinfo HTTP/1.1
048 * Host: server.example.com
049 * Authorization: DPoP jo4kahphoh1ath4INaochohLeeshaiyo
050 * DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik...
051 * </pre>
052 *
053 * <p>Related specifications:
054 *
055 * <ul>
056 *     <li>OpenID Connect Core 1.0, section 5.3.1.
057 *     <li>OAuth 2.0 Bearer Token Usage (RFC6750), section 2.
058 *     <li>OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer
059 *         (DPoP) (draft-ietf-oauth-dpop-03), section 7.
060 * </ul>
061 */
062@Immutable
063public class UserInfoRequest extends ProtectedResourceRequest {
064
065
066        /**
067         * The HTTP method.
068         */
069        private final HTTPRequest.Method httpMethod;
070        
071        
072        /**
073         * Creates a new UserInfo HTTP GET request.
074         *
075         * @param uri         The URI of the UserInfo endpoint. May be
076         *                    {@code null} if the {@link #toHTTPRequest} method
077         *                    will not be used.
078         * @param accessToken An access token for the request. Must not be
079         *                    {@code null}.
080         */
081        public UserInfoRequest(final URI uri, final AccessToken accessToken) {
082        
083                this(uri, HTTPRequest.Method.GET, accessToken);
084        }
085        
086        
087        /**
088         * Creates a new UserInfo request.
089         *
090         * @param uri         The URI of the UserInfo endpoint. May be
091         *                    {@code null} if the {@link #toHTTPRequest} method
092         *                    will not be used.
093         * @param httpMethod  The HTTP method. Must be HTTP GET or POST and not 
094         *                    {@code null}.
095         * @param accessToken An access token for the request. Must not be
096         *                    {@code null}.
097         */
098        public UserInfoRequest(final URI uri, final HTTPRequest.Method httpMethod, final AccessToken accessToken) {
099        
100                super(uri, accessToken);
101                
102                if (httpMethod == null)
103                        throw new IllegalArgumentException("The HTTP method must not be null");
104                
105                this.httpMethod = httpMethod;
106                
107                
108                if (accessToken == null)
109                        throw new IllegalArgumentException("The access token must not be null");
110        }
111        
112        
113        /**
114         * Gets the HTTP method for this UserInfo request.
115         *
116         * @return The HTTP method.
117         */
118        public HTTPRequest.Method getMethod() {
119        
120                return httpMethod;
121        }
122        
123        
124        @Override
125        public HTTPRequest toHTTPRequest() {
126                
127                if (getEndpointURI() == null)
128                        throw new SerializeException("The endpoint URI is not specified");
129
130                HTTPRequest httpRequest = new HTTPRequest(httpMethod, getEndpointURI());
131                
132                switch (httpMethod) {
133                
134                        case GET:
135                                httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader());
136                                break;
137                                
138                        case POST:
139                                httpRequest.setEntityContentType(ContentType.APPLICATION_URLENCODED);
140                                httpRequest.setQuery("access_token=" + getAccessToken().getValue());
141                                break;
142                        
143                        default:
144                                throw new SerializeException("Unexpected HTTP method: " + httpMethod);
145                }
146                
147                return httpRequest;
148        }
149        
150        
151        /**
152         * Parses the specified HTTP request for a UserInfo request.
153         *
154         * @param httpRequest The HTTP request. Must not be {@code null}.
155         *
156         * @return The UserInfo request.
157         *
158         * @throws ParseException If the HTTP request couldn't be parsed to a 
159         *                        UserInfo request.
160         */
161        public static UserInfoRequest parse(final HTTPRequest httpRequest)
162                throws ParseException {
163                
164                return new UserInfoRequest(
165                        httpRequest.getURI(),
166                        httpRequest.getMethod(),
167                        AccessToken.parse(httpRequest)
168                );
169        }
170}