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