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}