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