/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* docs/licenses/cddl.txt
* or http://www.opensource.org/licenses/cddl1.php.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* docs/licenses/cddl.txt. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2015-2016 UnboundID Corp.
*/
package com.unboundid.directory.sdk.examples;
import com.unboundid.directory.sdk.broker.api.AccessTokenValidator;
import com.unboundid.directory.sdk.broker.config.AccessTokenValidatorConfig;
import com.unboundid.directory.sdk.broker.types.BrokerContext;
import com.unboundid.directory.sdk.broker.types.TokenValidationResult;
import com.unboundid.scim2.common.GenericScimResource;
import com.unboundid.scim2.common.messages.ListResponse;
import com.unboundid.util.args.ArgumentParser;
import java.util.Arrays;
import java.util.HashSet;
/**
* Example Access Token Validator that processes access tokens issued from
* a fictional external IDP.
*
* The format of the fictional access token is:
*
* ExternalTestToken:[validity]:[owner]:[scope]
*
* ExternalTestToken: tells this validator that the token is one of "ours".
* validity: token is valid if this is equal to "TrustMe".
* owner: userName, for this example assumed to be common between
* the external IDP and local user store
* scope: OAuth2 scopes granted by this token, space-delimited
*/
public class ExampleAccessTokenValidator extends AccessTokenValidator {
/**
* Prefix for all tokens that can be validated this validator.
*/
public static final String TOKEN_PREFIX = "ExternalTestToken";
/**
* String value indicating that the token is valid.
*/
public static final String VALID_TOKEN = "TrustMe";
/**
* The SCIM endpoint that contains the local user records for token owners.
*/
public static final String USERS_ENDPOINT = "Users";
private BrokerContext serverContext;
@Override
public void initializeTokenValidator(
final BrokerContext serverContext,
final AccessTokenValidatorConfig config,
final ArgumentParser parser) throws Exception {
super.initializeTokenValidator(serverContext, config, parser);
this.serverContext = serverContext;
}
/**
* {@inheritDoc}
*/
@Override
public String getExtensionName() {
return "Example Access Token Validator";
}
/**
* {@inheritDoc}
*/
@Override
public String[] getExtensionDescription() {
return new String[0];
}
/**
* {@inheritDoc}
*/
@Override
public TokenValidationResult validate(
final String encodedAccessToken)
throws Exception {
TokenValidationResult tokenValidationResult = null;
String[] tokenParts = encodedAccessToken.split(":");
if (tokenParts.length == 4 && tokenParts[0].equals(TOKEN_PREFIX)) {
// this token is recognized, so populate a result object
boolean isValid = tokenParts[1].equals(VALID_TOKEN);
String userName = tokenParts[2];
String scope = tokenParts[3];
TokenValidationResult.Builder builder =
new TokenValidationResult.Builder(isValid);
// convert the user name into the Broker's required format for subject
// which is "SCIMEndpoint/SCIMId". This requires searching for the
// user's record in the local user store.
String filter = "username eq \"" + userName + "\"";
ListResponse<GenericScimResource> searchResults =
serverContext.getInternalScimInterface().search(
USERS_ENDPOINT, filter, GenericScimResource.class);
if (searchResults.getTotalResults() == 0) {
throw new Exception("No user found that matches token name.");
}
else if (searchResults.getTotalResults() > 1) {
throw new Exception("Found multiple users matching token user name.");
}
GenericScimResource localUser = searchResults.getResources().get(0);
builder.setSubjectToken(USERS_ENDPOINT + "/" + localUser.getId());
builder.setScope(new HashSet<String>(Arrays.asList(scope.split(" "))));
tokenValidationResult = builder.build();
}
return tokenValidationResult;
}
}