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