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; 030import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 031import com.nimbusds.oauth2.sdk.util.StringUtils; 032 033 034/** 035 * Bearer access token. 036 * 037 * <p>Example bearer access token serialised to JSON: 038 * 039 * <pre> 040 * { 041 * "access_token" : "2YotnFZFEjr1zCsicMWpAA", 042 * "token_type" : "bearer", 043 * "expires_in" : 3600, 044 * "scope" : "read write" 045 * } 046 * </pre> 047 * 048 * <p>The above example token serialised to a HTTP Authorization header: 049 * 050 * <pre> 051 * Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA 052 * </pre> 053 * 054 * <p>Related specifications: 055 * 056 * <ul> 057 * <li>OAuth 2.0 (RFC 6749), sections 1.4 and 5.1. 058 * <li>OAuth 2.0 Bearer Token Usage (RFC 6750). 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 * and scope are left undefined. 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 and scope are left undefined. 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. 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. 109 * 110 * @param byteLength The byte length of the value to generate. Must be 111 * greater than one. 112 * @param lifetime The lifetime in seconds, 0 if not specified. 113 * @param scope The scope, {@code null} if not specified. 114 */ 115 public BearerAccessToken(final int byteLength, final long lifetime, final Scope scope) { 116 117 super(AccessTokenType.BEARER, byteLength, lifetime, scope); 118 } 119 120 121 /** 122 * Creates a new minimal bearer access token with the specified value. 123 * The optional lifetime and scope are left undefined. 124 * 125 * @param value The access token value. Must not be {@code null} or 126 * empty string. 127 */ 128 public BearerAccessToken(final String value) { 129 130 this(value, 0L, null); 131 } 132 133 134 /** 135 * Creates a new bearer access token with the specified value and 136 * optional lifetime and scope. 137 * 138 * @param value The access token value. Must not be {@code null} or 139 * empty string. 140 * @param lifetime The lifetime in seconds, 0 if not specified. 141 * @param scope The scope, {@code null} if not specified. 142 */ 143 public BearerAccessToken(final String value, final long lifetime, final Scope scope) { 144 145 super(AccessTokenType.BEARER, value, lifetime, scope); 146 } 147 148 149 /** 150 * Returns the HTTP Authorization header value for this bearer access 151 * token. 152 * 153 * <p>Example: 154 * 155 * <pre> 156 * Authorization: Bearer eyJhbGciOiJIUzI1NiJ9 157 * </pre> 158 * 159 * @return The HTTP Authorization header. 160 */ 161 @Override 162 public String toAuthorizationHeader(){ 163 164 return "Bearer " + getValue(); 165 } 166 167 168 @Override 169 public boolean equals(final Object object) { 170 171 return object instanceof BearerAccessToken && 172 this.toString().equals(object.toString()); 173 } 174 175 176 /** 177 * Parses a bearer access token from a JSON object access token 178 * response. 179 * 180 * @param jsonObject The JSON object to parse. Must not be 181 * {@code null}. 182 * 183 * @return The bearer access token. 184 * 185 * @throws ParseException If the JSON object couldn't be parsed to a 186 * bearer access token. 187 */ 188 public static BearerAccessToken parse(final JSONObject jsonObject) 189 throws ParseException { 190 191 AccessTokenUtils.parseAndEnsureType(jsonObject, AccessTokenType.BEARER); 192 String accessTokenValue = AccessTokenUtils.parseValue(jsonObject); 193 long lifetime = AccessTokenUtils.parseLifetime(jsonObject); 194 Scope scope = AccessTokenUtils.parseScope(jsonObject); 195 return new BearerAccessToken(accessTokenValue, lifetime, scope); 196 } 197 198 199 /** 200 * Parses an HTTP Authorization header for a bearer access token. 201 * 202 * @param header The HTTP Authorization header value to parse. May be 203 * {@code null} if the header is missing, in which case 204 * an exception will be thrown. 205 * 206 * @return The bearer access token. 207 * 208 * @throws ParseException If the HTTP Authorization header value 209 * couldn't be parsed to a bearer access token. 210 */ 211 public static BearerAccessToken parse(final String header) 212 throws ParseException { 213 214 return new BearerAccessToken(AccessTokenUtils.parseValueFromHeader(header, AccessTokenType.BEARER)); 215 } 216 217 218 /** 219 * Parses a query or form parameters map for a bearer access token. 220 * 221 * @param parameters The query parameters. Must not be {@code null}. 222 * 223 * @return The bearer access token. 224 * 225 * @throws ParseException If a bearer access token wasn't found in the 226 * parameters. 227 */ 228 public static BearerAccessToken parse(final Map<String,List<String>> parameters) 229 throws ParseException { 230 231 if (! parameters.containsKey("access_token")) { 232 throw new ParseException("Missing access token parameter", BearerTokenError.MISSING_TOKEN); 233 } 234 235 String accessTokenValue = MultivaluedMapUtils.getFirstValue(parameters, "access_token"); 236 237 if (StringUtils.isBlank(accessTokenValue)) { 238 throw new ParseException("Blank / empty access token", BearerTokenError.INVALID_REQUEST); 239 } 240 241 return new BearerAccessToken(accessTokenValue); 242 } 243 244 245 246 /** 247 * Parses an HTTP request for a bearer access token. 248 * 249 * @param request The HTTP request to parse. Must not be {@code null}. 250 * 251 * @return The bearer access token. 252 * 253 * @throws ParseException If a bearer access token wasn't found in the 254 * HTTP request. 255 */ 256 public static BearerAccessToken parse(final HTTPRequest request) 257 throws ParseException { 258 259 // See http://tools.ietf.org/html/rfc6750#section-2 260 261 String authzHeader = request.getAuthorization(); 262 263 if (authzHeader != null) { 264 265 return parse(authzHeader); 266 } 267 268 // Try alternative token locations, form and query string are 269 // parameters are not differentiated here 270 271 Map<String,List<String>> params = request.getQueryParameters(); 272 273 return parse(params); 274 } 275}