001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * docs/licenses/cddl.txt 011 * or http://www.opensource.org/licenses/cddl1.php. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * docs/licenses/cddl.txt. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2016-2019 Ping Identity Corporation 026 */ 027 028 029package com.unboundid.directory.sdk.common.types; 030 031import com.unboundid.util.NotExtensible; 032 033import java.util.Collections; 034import java.util.Map; 035import java.util.Set; 036import java.util.concurrent.TimeUnit; 037 038/** 039 * Object returned from a request to an AccessTokenValidator to validate a 040 * token. The fields of this object are derived from the IETF OAuth 2.0 Token 041 * Introspection specification (RFC7662). 042 * <p> 043 * The decision as to whether an access token is accepted or not varies by 044 * product. For the Directory Server, Directory Proxy Server, 045 * Data Sync Server, or Data Metrics Server, different REST APIs 046 * may enforce different authorization rules, depending on their configuration; 047 * please refer to the relevant documentation. In general, a token's 048 * {@code active} property must be true. 049 * <p> 050 * For the Data Governance Server, authorization decisions are made by the policy 051 * engine. All properties of the TokenValidationResult may be accessed by 052 * policies; however, the default policy may only examine a subset of those 053 * properties (e.g. especially the {@code active} property). 054 */ 055@NotExtensible() 056public final class TokenValidationResult { 057 058 059 private final String accessToken; 060 061 private final Boolean active; 062 063 private final Set<String> scope; 064 065 private final String clientId; 066 067 private final String username; 068 069 private final String tokenType; 070 071 private final Long expirationTime; 072 073 private final Long issuedAt; 074 075 private final Long notUsedBefore; 076 077 private final String tokenSubject; 078 079 private final Set<String> audience; 080 081 private final String tokenIdentifier; 082 083 /** 084 * This field contains any extension values implemented by the 085 * Token Validator. 086 */ 087 private final Map<String,Object> additionalProperties; 088 089 /** 090 * Private constructor for builder. 091 * @param builder Builder source for properties. 092 */ 093 private TokenValidationResult(final Builder builder) 094 { 095 this.accessToken = builder.accessToken; 096 this.active = builder.active; 097 this.scope = builder.scope; 098 this.clientId = builder.clientId; 099 this.username = builder.username; 100 this.tokenType = builder.tokenType; 101 this.expirationTime = builder.expirationTime; 102 this.issuedAt = builder.issuedAt; 103 this.notUsedBefore = builder.notUsedBefore; 104 this.tokenSubject = builder.tokenSubject; 105 this.audience = builder.audience; 106 this.tokenIdentifier = builder.tokenIdentifier; 107 this.additionalProperties = (builder.additionalProperties == null) ? 108 Collections.<String,Object>emptyMap() : 109 builder.additionalProperties; 110 } 111 112 /** 113 * Get the actual access token as issued by the authorization server. 114 * @return the access token. May be null. 115 */ 116 public String getAccessToken() { 117 return accessToken; 118 } 119 120 /** 121 * Get whether the token is active. Per RFC 7662, a value of true for this 122 * property indicates that the given token was issued by the Token 123 * Validator's associated authorization server, has not been revoked by the 124 * resource owner, and is within its given time window of validity 125 * (e.g. after its issuance time and before its expiration time). 126 * @return the active state. 127 */ 128 public Boolean getActive() { 129 return active; 130 } 131 132 /** 133 * Get the scopes granted to this token. 134 * @return set of scope names. 135 */ 136 public Set<String> getScope() { 137 return scope; 138 } 139 140 /** 141 * Get the OAuth2 client Id of the client that requested the token. 142 * @return client Id string. 143 */ 144 public String getClientId() { 145 return clientId; 146 } 147 148 /** 149 * Get a human-readable user name for the resource owner that authorized 150 * the token. 151 * @return user name string. 152 */ 153 public String getUsername() { 154 return username; 155 } 156 157 /** 158 * Get the token type. The type of the token is defined in section 5.1 of 159 * OAuth 2.0 [RFC6749]. 160 * @return token type string. 161 */ 162 public String getTokenType() { 163 return tokenType; 164 } 165 166 /** 167 * Get the token expiration time in seconds since January 1 1970 UTC. 168 * @return expiration time in seconds. 169 */ 170 public Long getExpirationTime() { 171 return expirationTime; 172 } 173 174 /** 175 * Get the token issue time in seconds since January 1 1970 UTC. 176 * @return token issue time in seconds. 177 */ 178 public Long getIssuedAt() { 179 return issuedAt; 180 } 181 182 /** 183 * Get the not used before time in seconds since January 1 1070 UTC. 184 * @return not used before time in seconds. 185 */ 186 public Long getNotUsedBefore() { 187 return notUsedBefore; 188 } 189 190 /** 191 * Get the token subject as defined in JWT [RFC7519]. This value should 192 * contain the subject ID as known to the external authorization server rather 193 * than the local server. 194 * @return token subject string. 195 */ 196 public String getTokenSubject() { 197 return tokenSubject; 198 } 199 200 /** 201 * Get the token's intended audience(s). The audience is a Service-specific 202 * identifier representing the intended audience(s) for this token, as 203 * defined in JWT [RFC7519]. 204 * @return token audience. 205 */ 206 public Set<String> getAudience() { 207 return audience; 208 } 209 210 /** 211 * Get the unique identifier for this token. as defined in section 4.1.7 of 212 * JWT [RFC7519]. 213 * @return token unique identifier string. 214 */ 215 public String getTokenIdentifier() { 216 return tokenIdentifier; 217 } 218 219 /** 220 * Get any extension properties associated with the token. 221 * @return Map of property names to values. 222 */ 223 public Map<String, Object> getAdditionalProperties() { 224 return additionalProperties; 225 } 226 227 /** 228 * A Builder for TokenValidationResult. 229 */ 230 public static class Builder 231 { 232 private String accessToken; 233 private Boolean active; 234 private Set<String> scope; 235 private String clientId; 236 private String username; 237 private String tokenType; 238 private Long expirationTime; 239 private Long issuedAt; 240 private Long notUsedBefore; 241 private String tokenSubject; 242 private Set<String> audience; 243 private String tokenIdentifier; 244 private Map<String,Object> additionalProperties; 245 246 247 /** 248 * Creates a new builder object. 249 * @param active true if the token is active, false if not. Per RFC 250 * 7662, a value of true for this property indicates 251 * that the given token was issued by the Token 252 * Validator's associated authorization server, has not 253 * been revoked by the resource owner, and is within its 254 * given time window of validity (e.g. after its issuance 255 * time and before its expiration time). 256 */ 257 public Builder(final boolean active) 258 { 259 this(null, active); 260 } 261 262 /** 263 * Creates a new builder object. 264 * @param accessToken the actual access token, as received from the 265 * authorization server. May be null. 266 * @param active true if the token is active, false if not. Per RFC 267 * 7662, a value of true for this property indicates 268 * that the given token was issued by the Token 269 * Validator's associated authorization server, has not 270 * been revoked by the resource owner, and is within its 271 * given time window of validity (e.g. after its issuance 272 * time and before its expiration time). 273 */ 274 public Builder(final String accessToken, final boolean active) 275 { 276 this.accessToken = accessToken; 277 this.active = active; 278 setScope(Collections.<String>emptySet()); 279 } 280 281 /** 282 * Set the active field of the token validation result. 283 * 284 * @param active true if the token is active, false if not. Per RFC 7662, 285 * a value of true for this property indicates that the given 286 * token was issued by the Token Validator's associated 287 * authorization server, has not been revoked by the resource 288 * owner, and is within its given time window of validity 289 * (e.g. after its issuance time and before its expiration 290 * time). 291 * @return this. 292 */ 293 public Builder setActive(final boolean active) 294 { 295 this.active = active; 296 return this; 297 } 298 299 /** 300 * Set the optional scope field of the token validation result. 301 * 302 * @param scope A list of strings representing the scopes associated with 303 * this token. 304 * @return this. 305 */ 306 public Builder setScope(final Set<String> scope) 307 { 308 this.scope = (scope == null) ? Collections.<String>emptySet() : scope; 309 return this; 310 } 311 312 /** 313 * Set the optional clientId field of the token validation result. 314 * 315 * @param clientId Client identifier for the OAuth 2.0 client that 316 * requested this token. 317 * @return this. 318 */ 319 public Builder setClientId(final String clientId) 320 { 321 this.clientId = clientId; 322 return this; 323 } 324 325 /** 326 * Set the optional username field of the token validation result. 327 * 328 * @param username Human-readable identifier for the resource owner who 329 * authorized this token. 330 * @return this. 331 */ 332 public Builder setUsername(final String username) 333 { 334 this.username = username; 335 return this; 336 } 337 338 /** 339 * Set the optional tokenType field of the token validation result. 340 * 341 * @param tokenType Type of the token as defined in section 5.1 of OAuth 342 * 2.0 [RFC6749]. 343 * @return this. 344 */ 345 public Builder setTokenType(final String tokenType) 346 { 347 this.tokenType = tokenType; 348 return this; 349 } 350 351 /** 352 * Set the optional expirationTime field of the token validation result. 353 * 354 * @param expirationTime Integer timestamp, measured in the number of 355 * time units since January 1 1970 UTC, indicating 356 * when this token will expire. 357 * @param timeUnit the time units of the specified expiration time. 358 * @return this. 359 */ 360 public Builder setExpirationTime( 361 final long expirationTime, 362 final TimeUnit timeUnit) 363 { 364 this.expirationTime = timeUnit.toSeconds(expirationTime); 365 return this; 366 } 367 368 /** 369 * Set the optional issuedAt field of the token validation result. 370 * 371 * @param issuedAt Integer timestamp, measured in the number of time 372 * units since January 1 1970 UTC, indicating when this 373 * token was originally issued. 374 * @param timeUnit the time units of the specified issuedAt time. 375 * @return this. 376 */ 377 public Builder setIssuedAt( 378 final long issuedAt, 379 final TimeUnit timeUnit) 380 { 381 this.issuedAt = timeUnit.toSeconds(issuedAt); 382 return this; 383 } 384 385 /** 386 * Set the optional notUsedBefore field of the token validation result. 387 * 388 * @param notUsedBefore Integer timestamp, measured in the number of 389 * time units since January 1 1970 UTC, indicating 390 * when this token is not to be used before. 391 * @param timeUnit the time units of the specified notUsedBefore time. 392 * @return this. 393 */ 394 public Builder setNotUsedBefore( 395 final long notUsedBefore, 396 final TimeUnit timeUnit) 397 { 398 this.notUsedBefore = timeUnit.toSeconds(notUsedBefore); 399 return this; 400 } 401 402 /** 403 * Set the optional subjectToken field of the token validation result. 404 * 405 * @param tokenSubject Subject of the token, as defined in JWT [RFC7519]. 406 * This value should contain the subject ID as known to 407 * the external authorization server rather than the 408 * local server. 409 * @return this. 410 */ 411 public Builder setTokenSubject(final String tokenSubject) 412 { 413 this.tokenSubject = tokenSubject; 414 return this; 415 } 416 417 /** 418 * Set the optional audience field of the token validation result. 419 * 420 * @param audience Service-specific identifiers representing the 421 * intended audience(s) for this token, as defined in 422 * JWT [RFC7519]. 423 * @return this. 424 */ 425 public Builder setAudience(final Set<String> audience) 426 { 427 this.audience = audience; 428 return this; 429 } 430 431 /** 432 * Set the optional tokenIdentifier field of the token validation result. 433 * 434 * @param tokenIdentifier Unique string identifier for the token, as 435 * defined in section 4.1.7 of JWT [RFC7519]. 436 * @return this. 437 */ 438 public Builder setTokenIdentifier(final String tokenIdentifier) 439 { 440 this.tokenIdentifier = tokenIdentifier; 441 return this; 442 } 443 444 /** 445 * Set the optional additionalProperties field of the token validation 446 * result. 447 * @param properties Map of property names to values, containing any 448 * extension values implemented by the 449 * AccessTokenValidator. 450 * @return this. 451 */ 452 public Builder setAdditionalProperties( 453 final Map<String,Object> properties) { 454 455 this.additionalProperties = properties; 456 return this; 457 } 458 459 /** 460 * Builds a new TokenValidationResult from the parameters 461 * previously supplied to the builder. 462 * 463 * @return a new TokenValidationResult. 464 */ 465 public TokenValidationResult build() 466 { 467 return new TokenValidationResult(this); 468 } 469 } 470 471}