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