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