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.HashSet; 022import java.util.Set; 023 024import net.minidev.json.JSONObject; 025 026import com.nimbusds.oauth2.sdk.ParseException; 027import com.nimbusds.oauth2.sdk.Scope; 028 029 030/** 031 * The base abstract class for access tokens. Concrete extending classes should 032 * be immutable. 033 * 034 * <p>Related specifications: 035 * 036 * <ul> 037 * <li>OAuth 2.0 (RFC 6749), sections 1.4 and 5.1. 038 * </ul> 039 */ 040public abstract class AccessToken extends Token { 041 042 043 /** 044 * The access token type. 045 */ 046 private final AccessTokenType type; 047 048 049 /** 050 * Optional lifetime, in seconds. 051 */ 052 private final long lifetime; 053 054 055 /** 056 * Optional scope. 057 */ 058 private final Scope scope; 059 060 061 /** 062 * Creates a new minimal access token with a randomly generated 256-bit 063 * (32-byte) value, Base64URL-encoded. The optional lifetime and scope 064 * are left undefined. 065 * 066 * @param type The access token type. Must not be {@code null}. 067 */ 068 public AccessToken(final AccessTokenType type) { 069 070 this(type, 32); 071 } 072 073 074 /** 075 * Creates a new minimal access token with a randomly generated value 076 * of the specified byte length, Base64URL-encoded. The optional 077 * lifetime and scope are left undefined. 078 * 079 * @param type The access token type. Must not be {@code null}. 080 * @param byteLength The byte length of the value to generate. Must be 081 * greater than one. 082 */ 083 public AccessToken(final AccessTokenType type, final int byteLength) { 084 085 this(type, byteLength, 0L, null); 086 } 087 088 089 /** 090 * Creates a new access token with a randomly generated 256-bit 091 * (32-byte) value, Base64URL-encoded. 092 * 093 * @param type The access token type. Must not be {@code null}. 094 * @param lifetime The lifetime in seconds, 0 if not specified. 095 * @param scope The scope, {@code null} if not specified. 096 */ 097 public AccessToken(final AccessTokenType type, 098 final long lifetime, 099 final Scope scope) { 100 101 this(type, 32, lifetime, scope); 102 } 103 104 105 /** 106 * Creates a new access token with a randomly generated value 107 * of the specified byte length, Base64URL-encoded, and optional 108 * lifetime and scope. 109 * 110 * @param type The access token type. Must not be {@code null}. 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 AccessToken(final AccessTokenType type, 117 final int byteLength, 118 final long lifetime, 119 final Scope scope) { 120 121 super(byteLength); 122 123 if (type == null) 124 throw new IllegalArgumentException("The access token type must not be null"); 125 126 this.type = type; 127 128 this.lifetime = lifetime; 129 this.scope = scope; 130 } 131 132 133 /** 134 * Creates a new minimal access token with the specified value. The 135 * optional lifetime and scope are left undefined. 136 * 137 * @param type The access token type. Must not be {@code null}. 138 * @param value The access token value. Must not be {@code null} or 139 * empty string. 140 */ 141 public AccessToken(final AccessTokenType type, final String value) { 142 143 this(type, value, 0L, null); 144 } 145 146 147 /** 148 * Creates a new access token with the specified value and optional 149 * lifetime and scope. 150 * 151 * @param type The access token type. Must not be {@code null}. 152 * @param value The access token value. Must not be {@code null} or 153 * empty string. 154 * @param lifetime The lifetime in seconds, 0 if not specified. 155 * @param scope The scope, {@code null} if not specified. 156 */ 157 public AccessToken(final AccessTokenType type, 158 final String value, 159 final long lifetime, 160 final Scope scope) { 161 162 super(value); 163 164 if (type == null) 165 throw new IllegalArgumentException("The access token type must not be null"); 166 167 this.type = type; 168 169 this.lifetime = lifetime; 170 this.scope = scope; 171 } 172 173 174 /** 175 * Returns the access token type. 176 * 177 * @return The access token type. 178 */ 179 public AccessTokenType getType() { 180 181 return type; 182 } 183 184 185 /** 186 * Returns the lifetime of this access token. 187 * 188 * @return The lifetime in seconds, 0 if not specified. 189 */ 190 public long getLifetime() { 191 192 return lifetime; 193 } 194 195 196 /** 197 * Returns the scope of this access token. 198 * 199 * @return The scope, {@code null} if not specified. 200 */ 201 public Scope getScope() { 202 203 return scope; 204 } 205 206 207 @Override 208 public Set<String> getParameterNames() { 209 210 Set<String> paramNames = new HashSet<>(); 211 paramNames.add("access_token"); 212 paramNames.add("token_type"); 213 214 if (getLifetime() > 0) 215 paramNames.add("expires_in"); 216 217 if (getScope() != null) 218 paramNames.add("scope"); 219 220 return paramNames; 221 } 222 223 224 @Override 225 public JSONObject toJSONObject() { 226 227 JSONObject o = new JSONObject(); 228 229 o.put("access_token", getValue()); 230 o.put("token_type", type.toString()); 231 232 if (getLifetime() > 0) 233 o.put("expires_in", lifetime); 234 235 if (getScope() != null) 236 o.put("scope", scope.toString()); 237 238 return o; 239 } 240 241 242 @Override 243 public String toJSONString() { 244 245 return toJSONObject().toString(); 246 } 247 248 249 /** 250 * Returns the {@code Authorization} HTTP request header value for this 251 * access token. 252 * 253 * @return The {@code Authorization} header value. 254 */ 255 public abstract String toAuthorizationHeader(); 256 257 258 /** 259 * Parses an access token from a JSON object access token response. 260 * Only bearer access tokens are supported. 261 * 262 * @param jsonObject The JSON object to parse. Must not be 263 * {@code null}. 264 * 265 * @return The access token. 266 * 267 * @throws ParseException If the JSON object couldn't be parsed to an 268 * access token. 269 */ 270 public static AccessToken parse(final JSONObject jsonObject) 271 throws ParseException { 272 273 return BearerAccessToken.parse(jsonObject); 274 } 275 276 277 /** 278 * Parses an {@code Authorization} HTTP request header value for an 279 * access token. Only bearer access token are supported. 280 * 281 * @param header The {@code Authorization} header value to parse. Must 282 * not be {@code null}. 283 * 284 * @return The access token. 285 * 286 * @throws ParseException If the {@code Authorization} header value 287 * couldn't be parsed to an access token. 288 */ 289 public static AccessToken parse(final String header) 290 throws ParseException { 291 292 return BearerAccessToken.parse(header); 293 } 294}