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                
102                if (getEndpointURI() == null)
103                        throw new SerializeException("The endpoint URI is not specified");
104
105                URL endpointURL;
106
107                try {
108                        endpointURL = getEndpointURI().toURL();
109
110                } catch (MalformedURLException e) {
111
112                        throw new SerializeException(e.getMessage(), e);
113                }
114        
115                HTTPRequest httpRequest = new HTTPRequest(httpMethod, endpointURL);
116                
117                switch (httpMethod) {
118                
119                        case GET:
120                                httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader());
121                                break;
122                                
123                        case POST:
124                                httpRequest.setContentType(CommonContentTypes.APPLICATION_URLENCODED);
125                                httpRequest.setQuery("access_token=" + getAccessToken().getValue());
126                                break;
127                        
128                        default:
129                                throw new SerializeException("Unexpected HTTP method: " + httpMethod);
130                }
131                
132                return httpRequest;
133        }
134        
135        
136        /**
137         * Parses the specified HTTP request for a UserInfo request.
138         *
139         * @param httpRequest The HTTP request. Must not be {@code null}.
140         *
141         * @return The UserInfo request.
142         *
143         * @throws ParseException If the HTTP request couldn't be parsed to a 
144         *                        UserInfo request.
145         */
146        public static UserInfoRequest parse(final HTTPRequest httpRequest)
147                throws ParseException {
148                
149                HTTPRequest.Method httpMethod = httpRequest.getMethod();
150                
151                BearerAccessToken accessToken = BearerAccessToken.parse(httpRequest);
152
153                URI endpointURI;
154
155                try {
156
157                        endpointURI = httpRequest.getURL().toURI();
158
159                } catch (URISyntaxException e) {
160
161                        throw new ParseException(e.getMessage(), e);
162                }
163        
164                return new UserInfoRequest(endpointURI, httpMethod, accessToken);
165        }
166}