RestSTSInstanceConfig.java revision 3744900be632496920d4c9aca8f94ba6db4dd882
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyrighted [year] [name of copyright owner]".
*
* Copyright 2013-2015 ForgeRock AS.
*/
/**
* Class which encapsulates all of the user-provided config information necessary to create an instance of the rest
* STS.
* It is an immutable object with getter methods to obtain all of the necessary information needed by the various
* guice modules and providers to inject the object graph corresponding to a fully-configured STS instance.
*
* For an explanation of what's going on with the builders in this class,
*
* Also attempted to marshal the RestSTSInstanceConfig to/from json with the jackson ObjectMapper. But I was adding
* @JsonSerialize and @JsonDeserialize annotations, and because builder-based classes don't expose ctors which
* take the complete field set, I would have to create @JsonCreator instances which would have to pull all of the
* values out of a map anyway, which is 75% of the way towards a hand-rolled json marshalling implementation based on
* json-fluent. So a hand-rolled implementation it is.
*/
public class RestSTSInstanceConfig extends STSInstanceConfig {
public abstract static class RestSTSInstanceConfigBuilderBase<T extends RestSTSInstanceConfigBuilderBase<T>> extends STSInstanceConfig.STSInstanceConfigBuilderBase<T> {
private DeploymentConfig deploymentConfig;
private RestSTSInstanceConfigBuilderBase() {
supportedTokenTranslations = new HashSet<>();
}
this.deploymentConfig = deploymentConfig;
return self();
}
public T addSupportedTokenTranslation(
boolean invalidateInterimOpenAMSession) {
return self();
}
return self();
}
public RestSTSInstanceConfig build() {
return new RestSTSInstanceConfig(this);
}
}
public static class RestSTSInstanceConfigBuilder extends RestSTSInstanceConfigBuilderBase<RestSTSInstanceConfigBuilder> {
protected RestSTSInstanceConfigBuilder self() {
return this;
}
}
private final DeploymentConfig deploymentConfig;
/*
Define the names of fields to aid in json marshalling. Note that these names match the names of the AttributeSchema
entries in restSTS.xml, as this aids in marshalling an instance of this class into the attribute map needed for
SMS persistence.
*/
public static final String SUPPORTED_TOKEN_TRANSLATIONS = SharedSTSConstants.SUPPORTED_TOKEN_TRANSFORMS;
super(builder);
/*
throw an exception if no SAML2Config is set, but a SAML token is specified as
output in one of the token transformations. Likewise for OIDC.
*/
if (this.saml2Config == null) {
throw new IllegalStateException("A SAML2 token is a transformation output, but no Saml2Config " +
"state has been specified to guide the production of SAML2 tokens.");
}
}
}
if (this.openIdConnectTokenConfig == null) {
throw new IllegalStateException("A OPENIDCONNECT token is a transformation output, but no OIDCTokenConfig " +
"state has been specified to guide the production of OIDC Id Tokens.");
}
}
}
}
public static RestSTSInstanceConfigBuilder builder() {
return new RestSTSInstanceConfigBuilder();
}
/**
* @return The RestDeploymentConfig instance which specifies the url of the deployed STS instance, its realm,
* and its OpenAM authN context for each validated token type.
*/
public DeploymentConfig getDeploymentConfig() {
return deploymentConfig;
}
/**
* @return The set of token transformation operations supported by this STS instance.
*/
return supportedTokenTranslations;
}
/**
* @return This method will return the sub-path at which the rest STS instance will be deployed (sub-path relative to the
* path of the Crest service fronting the STS). This string serves to identify the rest STS instance. This identifier
* is passed to the TokenGenerationService so that the TGS can issue instance-specific tokens (i.e. reflecting the
* KeystoreConfig and SAML2Config of the associated STS instance). This path is also the most specific element of the
* DN identifying the config in the SMS.
*
* This method will be called to obtain the id under which the RestSTSInstanceConfig state is stored in the SMS, and
* the caching of the Route entry added to the Crest Router (needs to be cached to be later removed). Because this
* resource will be accessed as a url, it cannot have a trailing slash, as this slash is removed in the http request.
*/
public String getDeploymentSubPath() {
}
sb.append('\t').append("supportedTokenTranslations: ").append(supportedTokenTranslations).append('\n');
}
if (other instanceof RestSTSInstanceConfig) {
return super.equals(otherConfig) &&
}
return false;
}
public int hashCode() {
}
}
return baseValue;
}
throw new NullPointerException("JsonValue cannot be null!");
}
if (!supportedTranslations.isList()) {
throw new IllegalStateException("Unexpected value for the " + SUPPORTED_TOKEN_TRANSLATIONS + " field: "
}
}
}
/*
This method will marshal this state into the Map<String>, Set<String>> required for persistence in the SMS. The intent
is to leverage the toJson functionality, as a JsonValue is essentially a map, with the following exceptions:
1. the non-complex objects are not Set<String>, but rather <String>, and thus must be marshaled to a Set<String>. It seems
like I could go through all of the values in the map, and if any entry is simply a String, I could marshal it to a Set<String>
2. the complex objects (e.g. deploymentConfig, saml2Config, supportedTokenTranslations, etc) are themselves maps, and
thus must be 'flattened' into a single map. This is done by calling each of these encapsulated objects to provide a
map representation, and then insert these values into the top-level map.
*/
/*
Here the values are already contained in a set. I want to remove the referenced complex-object, but
then add each of the TokenTransformConfig instances in the supportTokenTranslationsSet to a Set<String>, obtaining
a string representation for each TokenTransformConfig instance, and adding it to the Set<String>
*/
}
if (saml2Config != null) {
}
if (openIdConnectTokenConfig != null) {
}
return interimMap;
}
/*
When we are marshaling back from a Map<String, Set<String>>, this Map contains all of the values, also those
contributed by encapsulated complex objects. So the structure must be 'un-flattened', where the top-level map
is passed to encapsulated complex-objects, so that they may re-constitute themselves, and then the top-level json entry
key is set to point at these re-constituted complex objects.
Not that the marshalToAttributeMap first calls toJson to obtain the map representation, albeit with hierarchical
elements, which must be subsequently flattened. The 'flattening' performed by the marshalToAttributeMap must then
be 'inverted' by this method, where all complex objects are re-constituted, using the state in the flattened map.
*/
public static RestSTSInstanceConfig marshalFromAttributeMap(Map<String, Set<String>> attributeMap) {
if (saml2Config != null) {
}
OpenIdConnectTokenConfig openIdConnectTokenConfig = OpenIdConnectTokenConfig.marshalFromAttributeMap(attributeMap);
if (openIdConnectTokenConfig != null) {
}
/*
The SUPPORTED_TOKEN_TRANSLATIONS are currently each in a String representation in the Set<String> map entry corresponding
to the SUPPORTED_TOKEN_TRANSLATIONS key. I need to marshal each back into a TokenTransformConfig instance, and then
call toJson on each, and put them in a JsonValue wrapping a list.
*/
}
}
/*
When the RestSecurityTokenServiceViewBean harvests the configurations input by the user, it attempts to publish the
JsonValue wrapping this Map<String, Set<String>>. It cannot directly attempt to marshal these configuration properties
in the ViewBean class, as this would introduce a dependency on the rest-sts into the openam-console module. Thus the
RestSecurityTokenServiceViewBean can only invoke the rest-sts-publish service with a JsonValue wrapping the
Map<String, Set<String>>.
This method will be invoked with the JsonValue generated by wrapping a Map<String, List<String>>
containing the user's rest-sts-configurations. It will turn the Map<String, List<String>> wrapped by the JsonValue back into
a raw Map<String, Set<String>>, and call marshalFromAttributeMap.
*/
public static RestSTSInstanceConfig marshalFromJsonAttributeMap(JsonValue jsonValue) throws IllegalStateException {
throw new IllegalStateException("JsonValue cannot be null!");
}
throw new IllegalStateException("In RestSTSInstanceConfig#marshalFromJsonAttributeMap, Passed-in JsonValue " +
}
} else if(!value.isCollection()) {
throw new IllegalStateException("In RestSTSInstanceConfig#marshalFromJsonAttributeMap, value " +
} else {
}
}
return marshalFromAttributeMap(smsMap);
}
}