com.nimbusds.openid.connect.provider.spi.grants.AccessTokenSpec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of c2id-server-sdk Show documentation
Show all versions of c2id-server-sdk Show documentation
SDK for Connect2id Server extensions, such as OpenID Connect claims
sources and OAuth 2.0 grant handlers
package com.nimbusds.openid.connect.provider.spi.grants;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.id.Audience;
import com.nimbusds.oauth2.sdk.id.Subject;
import com.nimbusds.oauth2.sdk.token.TokenEncoding;
import com.nimbusds.oauth2.sdk.util.CollectionUtils;
import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
import com.nimbusds.openid.connect.sdk.SubjectType;
import net.jcip.annotations.Immutable;
import net.minidev.json.JSONObject;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* Access token specification.
*/
@Immutable
public class AccessTokenSpec extends TokenSpec {
/**
* The default access token specification.
*
*
* - No explicit token lifetime is specified, to let the
* Connect2id server apply the default configured lifetime for
* access tokens.
*
- No explicit token audience is specified.
*
- No subject in impersonation and delegation cases is
* specified.
*
- The token is self-contained (JWT-encoded) and the optional
* encryption preference is not set.
*
- The access token subject type is public.
*
*/
public static final AccessTokenSpec DEFAULT = new AccessTokenSpec();
/**
* The access token encoding.
*/
private final TokenEncoding encoding;
/**
* The optional encryption preference for self-contained access
* tokens.
*/
private final Optional encryptSelfContained;
/**
* The access token subject type.
*/
private final SubjectType subjectType;
/**
* Creates a new default access token specification. No explicit
* token lifetime is specified (to let the Connect2id server apply the
* default configured lifetime for access tokens). No explicit token
* audience is specified. No subject in impersonation and delegation
* cases is specified. The token is self-contained (JWT-encoded) and
* the optional encryption preference is not set. The access token
* subject type is public.
*/
public AccessTokenSpec() {
this(0L, null, TokenEncoding.SELF_CONTAINED, null, Optional.empty(), SubjectType.PUBLIC);
}
/**
* Creates a new access token specification. No explicit token audience
* is specified. No subject in impersonation and delegation cases is
* specified. The access token subject type is public.
*
* @param lifetime The access token lifetime, in seconds, zero if not
* specified (to let the Connect2id server apply the
* default configured lifetime for access tokens).
* @param encoding The access token encoding. Must not be {@code null}.
* @param encrypt If {@code true} flags the access token for
* encryption. Applies to self-contained (JWT) access
* tokens only.
*/
@Deprecated
public AccessTokenSpec(final long lifetime,
final TokenEncoding encoding,
final boolean encrypt) {
this(lifetime, null, encoding, null, encrypt);
}
/**
* Creates a new access token specification. No subject in
* impersonation and delegation cases is specified. The access token
* subject type is public.
*
* @param lifetime The access token lifetime, in seconds, zero if not
* specified (to let the Connect2id server apply the
* default configured lifetime for access tokens).
* @param audList Explicit list of audiences for the access token,
* {@code null} if not specified.
* @param encoding The access token encoding. Must not be {@code null}.
* @param encrypt If {@code true} flags the access token for
* encryption. Applies to self-contained (JWT) access
* tokens only.
*/
@Deprecated
public AccessTokenSpec(final long lifetime,
final @Nullable List audList,
final TokenEncoding encoding,
final boolean encrypt) {
this(lifetime, audList, encoding, null, encrypt);
}
/**
* Creates a new access token specification. The access token subject
* type is public.
*
* @param lifetime The access token lifetime, in seconds,
* zero if not specified (to let the
* Connect2id server apply the default
* configured lifetime for access tokens).
* @param audList Explicit list of audiences for the access
* token, {@code null} if not specified.
* @param encoding The access token encoding. Must not be
* {@code null}.
* @param impersonatedSubject The subject in impersonation and
* delegation cases, {@code null} if not
* applicable.
* @param encrypt If {@code true} flags the access token
* for encryption. Applies to self-contained
* (JWT) access tokens only.
*/
@Deprecated
public AccessTokenSpec(final long lifetime,
final @Nullable List audList,
final TokenEncoding encoding,
final @Nullable Subject impersonatedSubject,
final boolean encrypt) {
this(lifetime, audList, encoding, impersonatedSubject, Optional.of(encrypt), SubjectType.PUBLIC);
}
/**
* Creates a new access token specification.
*
* @param lifetime The access token lifetime, in seconds,
* zero if not specified (to let the
* Connect2id server apply the default
* configured lifetime for access tokens).
* @param audList Explicit list of audiences for the access
* token, {@code null} if not specified.
* @param encoding The access token encoding. Must not be
* {@code null}.
* @param impersonatedSubject The subject in impersonation and
* delegation cases, {@code null} if not
* applicable.
* @param encrypt If {@code true} flags the access token
* for encryption. Applies to self-contained
* (JWT) access tokens only.
* @param subjectType The access token subject type.
*/
@Deprecated
public AccessTokenSpec(final long lifetime,
final @Nullable List audList,
final TokenEncoding encoding,
final @Nullable Subject impersonatedSubject,
final boolean encrypt,
final SubjectType subjectType) {
this(lifetime, audList, encoding, impersonatedSubject, Optional.of(encrypt), subjectType);
}
/**
* Creates a new access token specification. No subject in
* impersonation and delegation cases is specified. The access token
* subject type is public.
*
* @param lifetime The access token lifetime, in seconds,
* zero if not specified (to let the
* Connect2id server apply the default
* configured lifetime for access tokens).
* @param audList Explicit list of audiences for the
* access token, {@code null} if not
* specified.
* @param encoding The access token encoding. Must not be
* {@code null}.
* @param encryptSelfContained The optional encryption preference for
* self-contained (JWT) access tokens.
* Must not be {@code null}.
*/
public AccessTokenSpec(final long lifetime,
final @Nullable List audList,
final TokenEncoding encoding,
final Optional encryptSelfContained) {
this(lifetime, audList, encoding, null, encryptSelfContained, SubjectType.PUBLIC);
}
/**
* Creates a new access token specification.
*
* @param lifetime The access token lifetime, in seconds,
* zero if not specified (to let the
* Connect2id server apply the default
* configured lifetime for access tokens).
* @param audList Explicit list of audiences for the
* access token, {@code null} if not
* specified.
* @param encoding The access token encoding. Must not be
* {@code null}.
* @param impersonatedSubject The subject in impersonation and
* delegation cases, {@code null} if not
* applicable.
* @param encryptSelfContained The optional encryption preference for
* self-contained (JWT) access tokens.
* Must not be {@code null}.
* @param subjectType The access token subject type.
*/
public AccessTokenSpec(final long lifetime,
final @Nullable List audList,
final TokenEncoding encoding,
final @Nullable Subject impersonatedSubject,
final Optional encryptSelfContained,
final SubjectType subjectType) {
super(lifetime, audList, impersonatedSubject);
this.encoding = Objects.requireNonNull(encoding);
Objects.requireNonNull(encryptSelfContained);
// Only JWT tokens may be encrypted
this.encryptSelfContained = TokenEncoding.SELF_CONTAINED.equals(encoding) ? encryptSelfContained : Optional.empty();
if (subjectType == null) {
throw new IllegalArgumentException("The access token subject type must not be null");
}
if (SubjectType.PAIRWISE.equals(subjectType) && CollectionUtils.isEmpty(audList)) {
throw new IllegalArgumentException("The pairwise token subject type requires an explicit token audience");
}
this.subjectType = subjectType;
}
/**
* Returns the access token encoding.
*
* @return The access token encoding.
*/
public TokenEncoding getEncoding() {
return encoding;
}
/**
* Returns the access token encryption flag.
*
* @return If {@code true} the access token is flagged for encryption.
* Applies to self-contained access tokens only.
*
* @deprecated Use {@link #getEncryptSelfContained} instead.
*/
@Deprecated
public boolean encrypt() {
return encryptSelfContained.orElse(false);
}
/**
* Returns the optional encryption preference for self-contained (JWT)
* access tokens.
*
* @return The encryption preference.
*/
public Optional getEncryptSelfContained() {
return encryptSelfContained;
}
/**
* Returns the access token subject type.
*
* @return The subject type.
*/
public SubjectType getSubjectType() {
return subjectType;
}
@Override
public JSONObject toJSONObject() {
JSONObject o = super.toJSONObject();
if (getLifetime() <= 0) {
// Implies not specified - remove
o.remove("lifetime");
}
o.put("encoding", encoding.toString());
if (encoding.equals(TokenEncoding.SELF_CONTAINED) && encryptSelfContained.isPresent()) {
o.put("encrypt", encryptSelfContained.get());
}
o.put("sub_type", getSubjectType().toString().toUpperCase());
return o;
}
/**
* Parses an access token specification from the specified JSON object.
*
* @param jsonObject The JSON object. Must not be {@code null}.
*
* @return The access token specification.
*
* @throws ParseException If parsing failed.
*/
public static AccessTokenSpec parse(final JSONObject jsonObject)
throws ParseException {
TokenSpec tokenSpec = TokenSpec.parse(jsonObject);
// Adjust lifetime value for not specified (0)
long lifetime = tokenSpec.getLifetime() > 0 ? tokenSpec.getLifetime() : 0;
TokenEncoding encoding = TokenEncoding.SELF_CONTAINED;
Optional encryptSelfContained = Optional.empty();
if (jsonObject.get("encoding") != null) {
String c = JSONObjectUtils.getString(jsonObject, "encoding");
try {
encoding = TokenEncoding.valueOf(c.toUpperCase());
} catch (IllegalArgumentException e) {
throw new ParseException("Invalid access token encoding");
}
}
if (encoding.equals(TokenEncoding.SELF_CONTAINED)) {
if (jsonObject.get("encrypt") != null) {
encryptSelfContained = Optional.of(JSONObjectUtils.getBoolean(jsonObject, "encrypt"));
}
}
SubjectType subjectType = JSONObjectUtils.getEnum(jsonObject, "sub_type", SubjectType.class, SubjectType.PUBLIC);
try {
return new AccessTokenSpec(
lifetime,
tokenSpec.getAudience(),
encoding,
tokenSpec.getImpersonatedSubject(),
encryptSelfContained,
subjectType
);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage(), e);
}
}
}