/*******************************************************************************
*
* Copyright (c) 2004-2010, Oracle Corporation
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
*
*
*
*******************************************************************************/
package hudson.security;
import java.io.IOException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
/**
* Handles authentication for CLI commands.
*
* <p> {@link CliAuthenticator} is used to authenticate an invocation of the CLI
* command, so that the thread carries the correct {@link Authentication} that
* represents the user who's invoking the command.
*
* <h2>Lifecycle</h2> <p> Each time a CLI command is invoked,
* {@link SecurityRealm#createCliAuthenticator(CLICommand)} is called to
* allocate a fresh {@link CliAuthenticator} object.
*
* <p> The {@link Option} and {@link Argument} annotations on the returned
* {@link CliAuthenticator} instance are scanned and added into the
* {@link CmdLineParser}, then that parser is used to parse command line
* arguments. This means subtypes can define fields/setters with those
* annotations to define authentication-specific options to CLI commands.
*
* <p> Once the arguments and options are parsed and populated,
* {@link #authenticate()} method is called to perform the authentications. If
* the authentication succeeds, this method returns an {@link Authentication}
* instance that represents the user. If the authentication fails, this method
* throws {@link AuthenticationException}. To authenticate, the method can use
* parsed argument/option values, as well as interacting with the client via
* {@link CLICommand} by using its stdin/stdout and its channel (for example, if
* you want to interactively prompt a password, you can do so by using
* {@link CLICommand#channel}.)
*
* <p> If no explicit credential is provided, or if the {@link SecurityRealm}
* depends on a mode of authentication that doesn't involve in explicit password
* (such as Kerberos), it's also often useful to fall back to
* {@link CLICommand#getTransportAuthentication()}, in case the user is
* authenticated at the transport level.
*
* <p> Many commands do not require any authentication (for example, the "help"
* command), and still more commands can be run successfully with the anonymous
* permission. So the authenticator should normally allow unauthenticated CLI
* command invocations. For those, return {@link Hudson#ANONYMOUS} from the
* {@link #authenticate()} method.
*
* <h2>Example</h2> <p> For a complete example, see the implementation of
* {@link AbstractPasswordBasedSecurityRealm#createCliAuthenticator(CLICommand)}
*
* @author Kohsuke Kawaguchi
* @since 1.350
*/
public abstract class CliAuthenticator {
/**
* Authenticates the CLI invocation. See class javadoc for the semantics.
*
* @throws AuthenticationException If the authentication failed and hence
* the processing shouldn't proceed.
* @throws IOException Can be thrown if the {@link CliAuthenticator} fails
* to interact with the client. This exception is treated as a failure of
* authentication. It's just that allowing this would often simplify the
* callee.
* @throws InterruptedException Same motivation as {@link IOException}.
* Treated as an authentication failure.
*/
public abstract Authentication authenticate() throws AuthenticationException, IOException, InterruptedException;
}