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.oauth2.sdk.token;
019
020
021import com.nimbusds.oauth2.sdk.ParseException;
022import com.nimbusds.oauth2.sdk.Scope;
023import com.nimbusds.oauth2.sdk.http.HTTPRequest;
024import com.nimbusds.oauth2.sdk.rar.AuthorizationDetail;
025import net.jcip.annotations.Immutable;
026import net.minidev.json.JSONObject;
027
028import java.util.List;
029import java.util.Map;
030
031
032/**
033 * Bearer access token.
034 *
035 * <p>Example bearer access token serialised to JSON:
036 *
037 * <pre>
038 * {
039 *   "access_token" : "2YotnFZFEjr1zCsicMWpAA",
040 *   "token_type"   : "bearer",
041 *   "expires_in"   : 3600,
042 *   "scope"        : "read write"
043 * }
044 * </pre>
045 *
046 * <p>The above example token serialised to an HTTP Authorization header:
047 *
048 * <pre>
049 * Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
050 * </pre>
051 *
052 * <p>Related specifications:
053 *
054 * <ul>
055 *     <li>OAuth 2.0 (RFC 6749), sections 1.4 and 5.1.
056 *     <li>OAuth 2.0 Bearer Token Usage (RFC 6750).
057 *     <li>OAuth 2.0 Rich Authorization Requests (RFC 9396), section 7.
058 *     <li>OAuth 2.0 Token Exchange (RFC 8693), section 3.
059 * </ul>
060 */
061@Immutable
062public class BearerAccessToken extends AccessToken {
063        
064        
065        private static final long serialVersionUID = 2387121016151061194L;
066        
067        
068        /**
069         * Creates a new minimal bearer access token with a randomly generated 
070         * 256-bit (32-byte) value, Base64URL-encoded. The optional lifetime,
071         * scope and token type URI are left unspecified.
072         */
073        public BearerAccessToken() {
074        
075                this(32);
076        }       
077
078
079        /**
080         * Creates a new minimal bearer access token with a randomly generated 
081         * value of the specified byte length, Base64URL-encoded. The optional 
082         * lifetime, scope and token type URI are left unspecified.
083         *
084         * @param byteLength The byte length of the value to generate. Must be
085         *                   greater than one.
086         */
087        public BearerAccessToken(final int byteLength) {
088        
089                this(byteLength, 0L, null);
090        }
091
092
093        /**
094         * Creates a new bearer access token with a randomly generated 256-bit 
095         * (32-byte) value, Base64URL-encoded. The optional token type URI is
096         * left unspecified.
097         *
098         * @param lifetime The lifetime in seconds, 0 if not specified.
099         * @param scope    The scope, {@code null} if not specified.
100         */
101        public BearerAccessToken(final long lifetime, final Scope scope) {
102        
103                this(32, lifetime, scope);
104        }
105
106
107        /**
108         * Creates a new bearer access token with a randomly generated value of 
109         * the specified byte length, Base64URL-encoded. The optional token
110         * type URI is left unspecified.
111         *
112         * @param byteLength The byte length of the value to generate. Must be
113         *                   greater than one.
114         * @param lifetime   The lifetime in seconds, 0 if not specified.
115         * @param scope      The scope, {@code null} if not specified.
116         */
117        public BearerAccessToken(final int byteLength, final long lifetime, final Scope scope) {
118        
119                super(AccessTokenType.BEARER, byteLength, lifetime, scope);
120        }
121        
122        
123        /**
124         * Creates a new minimal bearer access token with the specified value.
125         * The optional lifetime, scope and token type URI are left
126         * unspecified.
127         *
128         * @param value The access token value. Must not be {@code null} or
129         *              empty string.
130         */
131        public BearerAccessToken(final String value) {
132        
133                this(value, 0L, null, null);
134        }
135
136        
137        /**
138         * Creates a new bearer access token with the specified value. The
139         * token type URI is left unspecified.
140         *
141         * @param value    The access token value. Must not be {@code null} or
142         *                 empty string.
143         * @param lifetime The lifetime in seconds, 0 if not specified.
144         * @param scope    The scope, {@code null} if not specified.
145         */
146        public BearerAccessToken(final String value, final long lifetime, final Scope scope) {
147
148                this(value, lifetime, scope, null);
149        }
150        
151        
152        /**
153         * Creates a new bearer access token with the specified value.
154         *
155         * @param value           The access token value. Must not be
156         *                        {@code null} or empty string.
157         * @param lifetime        The lifetime in seconds, 0 if not specified.
158         * @param scope           The scope, {@code null} if not specified.
159         * @param issuedTokenType The token type URI, {@code null} if not
160         *                        specified.
161         */
162        public BearerAccessToken(final String value,
163                                 final long lifetime,
164                                 final Scope scope,
165                                 final TokenTypeURI issuedTokenType) {
166        
167                super(AccessTokenType.BEARER, value, lifetime, scope, null, issuedTokenType);
168        }
169
170
171        /**
172         * Creates a new bearer access token with the specified value.
173         *
174         * @param value                The access token value. Must not be
175         *                             {@code null} or empty string.
176         * @param lifetime             The lifetime in seconds, 0 if not
177         *                             specified.
178         * @param scope                The scope, {@code null} if not
179         *                             specified.
180         * @param authorizationDetails The authorisation details, {@code null}
181         *                             if not specified.
182         * @param issuedTokenType      The token type URI, {@code null} if not
183         *                             specified.
184         */
185        public BearerAccessToken(final String value,
186                                 final long lifetime,
187                                 final Scope scope,
188                                 final List<AuthorizationDetail> authorizationDetails,
189                                 final TokenTypeURI issuedTokenType) {
190
191                super(AccessTokenType.BEARER, value, lifetime, scope, authorizationDetails, issuedTokenType);
192        }
193        
194        
195        /**
196         * Returns the HTTP Authorization header value for this bearer access 
197         * token.
198         *
199         * <p>Example:
200         *
201         * <pre>
202         * Authorization: Bearer eyJhbGciOiJIUzI1NiJ9
203         * </pre>
204         *
205         * @return The HTTP Authorization header.
206         */
207        @Override
208        public String toAuthorizationHeader(){
209        
210                return "Bearer " + getValue();
211        }
212        
213        
214        @Override
215        public boolean equals(final Object object) {
216        
217                return object instanceof BearerAccessToken &&
218                       this.toString().equals(object.toString());
219        }
220
221
222        /**
223         * Parses a bearer access token from a JSON object access token 
224         * response.
225         *
226         * @param jsonObject The JSON object to parse. Must not be 
227         *                   {@code null}.
228         *
229         * @return The bearer access token.
230         *
231         * @throws ParseException If the JSON object couldn't be parsed to a
232         *                        bearer access token.
233         */
234        public static BearerAccessToken parse(final JSONObject jsonObject)
235                throws ParseException {
236                
237                AccessTokenUtils.parseAndEnsureType(jsonObject, AccessTokenType.BEARER);
238                String accessTokenValue = AccessTokenUtils.parseValue(jsonObject);
239                long lifetime = AccessTokenUtils.parseLifetime(jsonObject);
240                Scope scope = AccessTokenUtils.parseScope(jsonObject);
241                List<AuthorizationDetail> authorizationDetails = AccessTokenUtils.parseAuthorizationDetails(jsonObject);
242                TokenTypeURI issuedTokenType = AccessTokenUtils.parseIssuedTokenType(jsonObject);
243                return new BearerAccessToken(accessTokenValue, lifetime, scope, authorizationDetails, issuedTokenType);
244        }
245        
246        
247        /**
248         * Parses an HTTP Authorization header for a bearer access token.
249         *
250         * @param header The HTTP Authorization header value to parse. May be
251         *               {@code null} if the header is missing, in which case
252         *               an exception will be thrown.
253         *
254         * @return The bearer access token.
255         *
256         * @throws ParseException If the HTTP Authorization header value 
257         *                        couldn't be parsed to a bearer access token.
258         */
259        public static BearerAccessToken parse(final String header)
260                throws ParseException {
261                
262                return new BearerAccessToken(AccessTokenUtils.parseValueFromHeader(header, AccessTokenType.BEARER));
263        }
264        
265        
266        /**
267         * Parses a query or form parameters map for a bearer access token.
268         *
269         * @param parameters The query parameters. Must not be {@code null}.
270         *
271         * @return The bearer access token.
272         *
273         * @throws ParseException If a bearer access token wasn't found in the
274         *                        parameters.
275         */
276        public static BearerAccessToken parse(final Map<String,List<String>> parameters)
277                throws ParseException {
278                
279                return new BearerAccessToken(AccessTokenUtils.parseValueFromQueryParameters(parameters, AccessTokenType.BEARER));
280        }
281        
282        
283        
284        /**
285         * Parses an HTTP request for a bearer access token.
286         * 
287         * @param request The HTTP request to parse. Must not be {@code null}.
288         * 
289         * @return The bearer access token.
290         * 
291         * @throws ParseException If a bearer access token wasn't found in the
292         *                        HTTP request.
293         */
294        public static BearerAccessToken parse(final HTTPRequest request)
295                throws ParseException {
296
297                // See http://tools.ietf.org/html/rfc6750#section-2
298                String authzHeader = request.getAuthorization();
299
300                if (authzHeader != null) {
301                        return parse(authzHeader);
302                }
303
304                // Try alternative token locations, form and query string are
305                // parameters are not differentiated here
306                Map<String,List<String>> params = request.getQueryParameters();
307                return parse(params);
308        }
309}