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