001 package com.nimbusds.oauth2.sdk.token; 002 003 004 import net.minidev.json.JSONObject; 005 006 import com.nimbusds.oauth2.sdk.ParseException; 007 import 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 */ 021 public 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 value. 046 * The value will be made up of 32 mixed-case alphanumeric ASCII 047 * characters. The optional lifetime and scope 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 length. The value will be made up of mixed-case 060 * alphanumeric ASCII characters. The optional lifetime and scope are 061 * left undefined. 062 * 063 * @param type The access token type. Must not be {@code null}. 064 * @param length The number of characters. Must be a positive integer. 065 */ 066 public AccessToken(final AccessTokenType type, final int length) { 067 068 this(type, length, 0l, null); 069 } 070 071 072 /** 073 * Creates a new access token with a randomly generated value and the 074 * specified optional lifetime and scope. The value will be made up of 075 * 32 mixed-case alphanumeric ASCII characters. 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 of the 091 * specified length and optional lifetime and scope. The value will be 092 * made up of mixed-case alphanumeric ASCII characters. 093 * 094 * @param type The access token type. Must not be {@code null}. 095 * @param length The number of characters. Must be a positive 096 * integer. 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 length, 102 final long lifetime, 103 final Scope scope) { 104 105 super(length); 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 * Gets 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 * Gets 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 * Gets 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 }