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-2018 Ping Identity Corporation 026 */ 027 028 029package com.unboundid.directory.sdk.broker.api; 030 031import com.unboundid.directory.sdk.broker.config.AccessTokenValidatorConfig; 032import com.unboundid.directory.sdk.broker.internal.BrokerExtension; 033import com.unboundid.directory.sdk.broker.types.BrokerContext; 034import com.unboundid.directory.sdk.broker.types.TokenValidationResult; 035import com.unboundid.directory.sdk.common.internal.Configurable; 036import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 037import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 038import com.unboundid.util.Extensible; 039import com.unboundid.util.ThreadSafety; 040import com.unboundid.util.ThreadSafetyLevel; 041import com.unboundid.util.args.ArgumentException; 042import com.unboundid.util.args.ArgumentParser; 043 044import java.util.Collections; 045import java.util.List; 046import java.util.Map; 047 048/** 049 * This class defines an API that may be implemented by Broker extensions 050 * that validate externally generated access tokens. Implementing extensions 051 * that support this API enables the Broker SCIM service to accept access 052 * tokens generated from external Identity Providers. 053 * 054 * <H2>Configuring Access Token Validators</H2> 055 * In order to configure an Access Token Validator created using this API, use 056 * a command like: 057 * <PRE> 058 * dsconfig create-token-validator \ 059 * ---validator-name "<I>{name}</I>" \ 060 * --type third-party \ 061 * --set "extension-class:<I>{class-name}</I>" \ 062 * --set "extension-argument:<I>{name=value}</I>" 063 * </PRE> 064 * where "<I>{name}</I>" is the name to use for the Access Token Validator 065 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class 066 * that extends 067 * {@code com.unboundid.directory.sdk.broker.api.TokenValidator}, 068 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to 069 * provide to the Access Token Validator. If multiple arguments should be 070 * provided to the extension, then the 071 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be 072 * provided multiple times. 073 */ 074@Extensible() 075@BrokerExtension 076@ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE) 077public abstract class AccessTokenValidator implements UnboundIDExtension, 078 Configurable, ExampleUsageProvider { 079 080 /** 081 * Creates a new instance of this Access Token Validator. All 082 * implementations must include a default constructor, but any 083 * initialization should generally be done in the 084 * {@link #initializeTokenValidator} method. 085 */ 086 public AccessTokenValidator() 087 { 088 // No implementation is required. 089 } 090 091 /** 092 * {@inheritDoc} 093 */ 094 @Override 095 public abstract String getExtensionName(); 096 097 098 099 /** 100 * {@inheritDoc} 101 */ 102 @Override 103 public abstract String[] getExtensionDescription(); 104 105 106 107 /** 108 * {@inheritDoc} 109 */ 110 @Override 111 public Map<List<String>,String> getExamplesArgumentSets() 112 { 113 return Collections.emptyMap(); 114 } 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public void defineConfigArguments(final ArgumentParser parser) 121 throws ArgumentException 122 { 123 // No arguments will be allowed by default. 124 } 125 126 127 /** 128 * Initializes this access token validator. 129 * 130 * @param serverContext A handle to the server context for the server in 131 * which this extension is running. 132 * @param config The general configuration for this token validator. 133 * @param parser The argument parser which has been initialized from 134 * the configuration for this token validator. 135 * 136 * @throws Exception If a problem occurs while initializing this 137 * token validator. 138 */ 139 public void initializeTokenValidator( 140 final BrokerContext serverContext, 141 final AccessTokenValidatorConfig config, 142 final ArgumentParser parser) 143 throws Exception 144 { 145 // No initialization will be performed by default. 146 } 147 148 149 /** 150 * Performs any cleanup which may be necessary when this token validator 151 * is to be taken out of service. 152 */ 153 public void finalizeTokenValidator() 154 { 155 // No implementation is performed by default. 156 } 157 158 159 /** 160 * Validate the provided access token. 161 * @param encodedAccessToken access token string as it is received from the 162 * requesting client. 163 * @return The Broker may be configured to accept access tokens from multiple 164 * sources so it is important that each validator differentiate between a 165 * token format that it does not recognize and a token that it can process 166 * but is not valid. 167 * 168 * If the token can be processed, the validator must return a 169 * TokenValidationResult object containing token properties. Most 170 * importantly the {@code active} field of the TokenValidationResult must be 171 * set by the validator. 172 * 173 * The decision as to whether an access token is accepted or not is made by 174 * the Broker's policy engine. All properties of the TokenValidationResult 175 * are available to XACML policies, however it is possible that policies 176 * may only examine a subset of those properties. When writing a new 177 * validator it is important to match up the properties exposed by the 178 * validator with the properties consulted by the default and/or custom 179 * policies. 180 * 181 * If the token cannot be introspected by the Access Token Validator it must 182 * return null to allow other validators to have a chance to process the 183 * token. 184 * 185 * @throws Exception if an error occurs during the processing of a token 186 * that can be introspected by the validator. Exceptions should only be 187 * thrown for unexpected internal errors. Sensitive information should not 188 * be included in the exception message as the message may be returned to 189 * the client application that has passed the token. 190 */ 191 public abstract TokenValidationResult validate(String encodedAccessToken) 192 throws Exception; 193 194}