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 * Portions Copyright 2021-2024 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.ds.api; 028 029 030 031import java.util.Collections; 032import java.util.List; 033 034import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 035import com.unboundid.directory.sdk.common.internal.Reconfigurable; 036import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 037import com.unboundid.directory.sdk.common.operation.SimpleBindRequest; 038import com.unboundid.directory.sdk.common.types.Entry; 039import com.unboundid.directory.sdk.common.types.OperationContext; 040import com.unboundid.directory.sdk.ds.config. 041 PassThroughAuthenticationHandlerConfig; 042import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 043import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 044import com.unboundid.directory.sdk.ds.types.PassThroughAuthenticationResult; 045import com.unboundid.ldap.sdk.Attribute; 046import com.unboundid.ldap.sdk.LDAPException; 047import com.unboundid.ldap.sdk.ResultCode; 048import com.unboundid.util.Extensible; 049import com.unboundid.util.NotNull; 050import com.unboundid.util.Nullable; 051import com.unboundid.util.ThreadSafety; 052import com.unboundid.util.ThreadSafetyLevel; 053import com.unboundid.util.args.ArgumentException; 054import com.unboundid.util.args.ArgumentParser; 055 056 057 058/** 059 * This class defines an API that must be implemented by extensions that 060 * attempt to pass through authentication to an external service. 061 * <BR> 062 * <H2>Configuring Pass-Through Authentication Handlers</H2> 063 * In order to configure a pass-through authentication handler created using 064 * this API, use a command like: 065 * <PRE> 066 * dsconfig create-pass-through-authentication-handler \ 067 * --handler-name "<I>{handler-name}</I>" \ 068 * --type third-party \ 069 * --set "extension-class:<I>{class-name}</I>" \ 070 * --set "extension-argument:<I>{name=value}</I>" 071 * </PRE> 072 * where "<I>{handler-name}</I>" is the name to use for the pass-through 073 * authentication handler instance, "<I>{class-name}</I>" is the fully-qualified 074 * name of the Java class that extends 075 * {@code com.unboundid.directory.sdk.ds.api.PassThroughAuthenticationHandler}, 076 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to 077 * provide to the handler. If multiple arguments should be provided to the 078 * pass-through authentication handler, then the 079 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be 080 * provided multiple times. 081 */ 082@Extensible() 083@DirectoryServerExtension() 084@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 085public abstract class PassThroughAuthenticationHandler 086 implements UnboundIDExtension, 087 Reconfigurable<PassThroughAuthenticationHandlerConfig>, 088 ExampleUsageProvider 089{ 090 /** 091 * Creates a new instance of this pass-through authentication handler. All 092 * pass-through authentication handler implementations must include a default 093 * constructor, but any initialization 094 * should generally be done in the 095 * {@link #initializePassThroughAuthenticationHandler} method. 096 */ 097 public PassThroughAuthenticationHandler() 098 { 099 // No implementation is required. 100 } 101 102 103 104 /** 105 * {@inheritDoc} 106 */ 107 @Override() 108 @NotNull() 109 public abstract String getExtensionName(); 110 111 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override() 117 @Nullable() 118 public abstract String[] getExtensionDescription(); 119 120 121 122 /** 123 * {@inheritDoc} 124 */ 125 public void defineConfigArguments(@NotNull final ArgumentParser parser) 126 throws ArgumentException 127 { 128 // No arguments will be allowed by default. 129 } 130 131 132 133 /** 134 * Initializes this pass-through authentication handler. 135 * 136 * @param serverContext A handle to the server context for the server in 137 * which this extension is running. It will not be 138 * {@code null}. 139 * @param config The general configuration for this pass-through 140 * authentication handler. It will not be 141 * {@code null}. 142 * @param parser The argument parser which has been initialized from 143 * the configuration for this pass-through 144 * authentication handler. It will not be 145 * {@code null}. 146 * 147 * @throws LDAPException If a problem occurs while initializing this 148 * pass-through authentication handler. 149 */ 150 public void initializePassThroughAuthenticationHandler( 151 @NotNull final DirectoryServerContext serverContext, 152 @NotNull final PassThroughAuthenticationHandlerConfig config, 153 @NotNull final ArgumentParser parser) 154 throws LDAPException 155 { 156 // No initialization will be performed by default. 157 } 158 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override() 165 public boolean isConfigurationAcceptable( 166 @NotNull final PassThroughAuthenticationHandlerConfig config, 167 @NotNull final ArgumentParser parser, 168 @NotNull final List<String> unacceptableReasons) 169 { 170 // No extended validation will be performed by default. 171 return true; 172 } 173 174 175 176 /** 177 * {@inheritDoc} 178 */ 179 @NotNull() 180 public ResultCode applyConfiguration( 181 @NotNull final PassThroughAuthenticationHandlerConfig config, 182 @NotNull final ArgumentParser parser, 183 @NotNull final List<String> adminActionsRequired, 184 @NotNull final List<String> messages) 185 { 186 // By default, no configuration changes will be applied. If there are any 187 // arguments, then add an admin action message indicating that the extension 188 // needs to be restarted for any changes to take effect. 189 if (! parser.getNamedArguments().isEmpty()) 190 { 191 adminActionsRequired.add( 192 "No configuration change has actually been applied. The new " + 193 "configuration will not take effect until this pass-through " + 194 "authentication handler is disabled and re-enabled or until " + 195 "the server is restarted."); 196 } 197 198 return ResultCode.SUCCESS; 199 } 200 201 202 203 /** 204 * Performs any cleanup which may be necessary when this pass-through 205 * authentication handler is to be taken out of service. 206 */ 207 public void finalizePassThroughAuthenticationHandler() 208 { 209 // No implementation is required. 210 } 211 212 213 214 /** 215 * Attempts to pass through authentication for the provided bind operation to 216 * the external service. 217 * 218 * @param operationContext The context for the bind operation. It will not 219 * be {@code null}. 220 * @param bindRequest The bind request being processed. It will not 221 * be {@code null}. 222 * @param localEntry The local entry for the account targeted by the 223 * bind operation. It will not be {@code null}. 224 * 225 * @return The result of the pass-through authentication attempt. It must 226 * not be {@code null}. 227 */ 228 @NotNull() 229 public abstract PassThroughAuthenticationResult 230 attemptPassThroughAuthentication( 231 @NotNull final OperationContext operationContext, 232 @NotNull final SimpleBindRequest bindRequest, 233 @NotNull final Entry localEntry); 234 235 236 237 /** 238 * Retrieves a list of any handler-specific attributes that should be included 239 * in the monitor entry for the associated pluggable pass-through 240 * authentication plugin. 241 * 242 * @return A list of any handler-specific attributes that should be included 243 * in the monitor entry for the associated plugin. It may be 244 * {@code null} or empty if no handler-specific monitor attributes 245 * should be included. 246 */ 247 @Nullable() 248 public List<Attribute> getMonitorAttributes() 249 { 250 return Collections.emptyList(); 251 } 252}