com.nimbusds.openid.connect.provider.spi.grants.SubjectAuthorization Maven / Gradle / Ivy
Show all versions of c2id-server-sdk Show documentation
package com.nimbusds.openid.connect.provider.spi.grants;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.oauth2.sdk.id.Subject;
import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
import com.nimbusds.openid.connect.sdk.claims.ACR;
import com.nimbusds.openid.connect.sdk.claims.AMR;
import net.jcip.annotations.Immutable;
import net.minidev.json.JSONObject;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* OAuth 2.0 / OpenID Connect authorisation produced by a {@link GrantHandler}
* specifying a subject (end-user) and permitting ID token issue.
*
* Required authorisation details:
*
*
* - The subject (end-user).
*
- The authorised scope.
*
*
* All other parameters are optional or have suitable defaults.
*/
@Immutable
public class SubjectAuthorization extends GrantAuthorization {
/**
* The identifier of the authorised subject.
*/
private final Subject subject;
/**
* The ID token specification.
*/
private final IDTokenSpec idTokenSpec;
/**
* Creates a new authorisation for the specified subject.
*
* @param subject The subject (end-user) identifier. Must not
* be {@code null}.
* @param scope The authorised scope values. Must not be
* {@code null}.
* @param accessTokenSpec The access token specification. Must not be
* {@code null}.
* @param idTokenSpec The ID token specification. Must not be
* {@code null}.
* @param claimsSpec The OpenID claims specification. Must not be
* {@code null}.
* @param data Additional data as a JSON object,
* {@code null} if not specified.
*/
public SubjectAuthorization(final Subject subject,
final Scope scope,
final AccessTokenSpec accessTokenSpec,
final IDTokenSpec idTokenSpec,
final ClaimsSpec claimsSpec,
final @Nullable JSONObject data) {
super(scope, accessTokenSpec, claimsSpec, data);
this.subject = Objects.requireNonNull(subject);
this.idTokenSpec = Objects.requireNonNull(idTokenSpec);
}
/**
* Returns the subject (end-user) identifier.
*
* @return The subject identifier.
*/
public Subject getSubject() {
return subject;
}
/**
* Returns the time of the subject authentication.
*
* @return The time of the subject authentication. If {@code null} it
* will be set to now. Applies only if an ID token is issued.
*/
public @Nullable Date getAuthTime() {
return getIDTokenSpec().getAuthTime();
}
/**
* Returns the Authentication Context Class Reference (ACR).
*
* @return The Authentication Context Class Reference (ACR),
* {@code null} if not specified. Applies only if an ID token
* is issued.
*/
public @Nullable ACR getACR() {
return getIDTokenSpec().getACR();
}
/**
* Returns The Authentication Methods Reference (AMR) list.
*
* @return The Authentication Methods Reference (AMR) list,
* {@code null} if not specified. Applies only if an ID token
* is issued.
*/
public @Nullable List getAMRList() {
return getIDTokenSpec().getAMRList();
}
/**
* Returns the ID token specification.
*
* @return The ID token specification.
*/
public IDTokenSpec getIDTokenSpec() {
return idTokenSpec;
}
@Override
public JSONObject toJSONObject() {
JSONObject o = super.toJSONObject();
o.put("sub", subject.getValue());
if (idTokenSpec.issue()) {
JSONObject idTokenJSONObject = idTokenSpec.toJSONObject();
// Move auth_time, acr and amr to top level
if (idTokenJSONObject.get("auth_time") != null) {
o.put("auth_time", idTokenJSONObject.remove("auth_time"));
}
if (idTokenJSONObject.get("acr") != null) {
o.put("acr", idTokenJSONObject.remove("acr"));
}
if (idTokenJSONObject.get("amr") != null) {
o.put("amr", idTokenJSONObject.remove("amr"));
}
o.put("id_token", idTokenJSONObject);
}
return o;
}
/**
* Parses a subject authorisation from the specified JSON object.
*
* @param jsonObject The JSON object to parse. Must not be {@code null}.
*
* @return The subject authorisation.
*
* @throws ParseException If parsing failed.
*/
public static SubjectAuthorization parse(final JSONObject jsonObject)
throws ParseException {
GrantAuthorization basicAuthz = GrantAuthorization.parse(jsonObject);
Subject sub = new Subject(JSONObjectUtils.getString(jsonObject, "sub"));
// Backward API compatibility
Date topLevelAuthTime = null;
if (jsonObject.containsKey("auth_time")) {
topLevelAuthTime = new Date(JSONObjectUtils.getLong(jsonObject, "auth_time") * 1000L);
}
ACR topLevelACR = null;
if (jsonObject.containsKey("acr")) {
topLevelACR = new ACR(JSONObjectUtils.getString(jsonObject, "acr"));
}
List topLevelAMRList = null;
if (jsonObject.containsKey("amr")) {
String[] sa = JSONObjectUtils.getStringArray(jsonObject, "amr");
topLevelAMRList = new ArrayList<>(sa.length);
for (String s: sa) {
topLevelAMRList.add(new AMR(s));
}
}
IDTokenSpec idSpec = new IDTokenSpec();
if (jsonObject.containsKey("id_token")) {
idSpec = IDTokenSpec.parse(JSONObjectUtils.getJSONObject(jsonObject, "id_token"));
// Override with top-level params where set
idSpec = new IDTokenSpec(
idSpec.issue(),
idSpec.getLifetime(),
topLevelAuthTime != null ? topLevelAuthTime : idSpec.getAuthTime(),
topLevelACR != null ? topLevelACR : idSpec.getACR(),
topLevelAMRList != null ? topLevelAMRList : idSpec.getAMRList(),
idSpec.getImpersonatedSubject());
}
return new SubjectAuthorization(
sub,
basicAuthz.getScope(),
basicAuthz.getAccessTokenSpec(),
idSpec,
basicAuthz.getClaimsSpec(),
basicAuthz.getData());
}
/**
* Parses a subject authorisation from the specified JSON object
* string.
*
* @param json The JSON object string to parse. Must not be
* {@code null}.
*
* @return The subject authorisation.
*
* @throws ParseException If parsing failed.
*/
public static SubjectAuthorization parse(final String json)
throws ParseException {
return parse(JSONObjectUtils.parse(json));
}
}