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