001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.authc.pam;
020    
021    import org.apache.shiro.authc.AuthenticationException;
022    import org.apache.shiro.authc.AuthenticationInfo;
023    import org.apache.shiro.authc.AuthenticationToken;
024    import org.apache.shiro.realm.Realm;
025    
026    import java.util.Collection;
027    
028    
029    /**
030     * A {@code AuthenticationStrategy} implementation assists the {@link ModularRealmAuthenticator} during the
031     * log-in process in a pluggable realm (PAM) environment.
032     *
033     * <p>The {@code ModularRealmAuthenticator} will consult implementations of this interface on what to do during each
034     * interaction with the configured Realms.  This allows a pluggable strategy of whether or not an authentication
035     * attempt must be successful for all realms, only 1 or more realms, no realms, etc.
036     *
037     * @see AllSuccessfulStrategy
038     * @see AtLeastOneSuccessfulStrategy
039     * @see FirstSuccessfulStrategy
040     * @since 0.2
041     */
042    public interface AuthenticationStrategy {
043    
044        /**
045         * Method invoked by the ModularAuthenticator signifying that the authentication process is about to begin for the
046         * specified {@code token} - called before any {@code Realm} is actually invoked.
047         *
048         * <p>The {@code AuthenticationInfo} object returned from this method is essentially an empty place holder for
049         * aggregating account data across multiple realms.  It should be populated by the strategy implementation over the
050         * course of authentication attempts across the multiple realms.  It will be passed into the
051         * {@link #beforeAttempt} calls, allowing inspection of the aggregated account data up to that point in the
052         * multi-realm authentication, allowing any logic to be executed accordingly.
053         *
054         * @param realms the Realms that will be consulted during the authentication process for the specified token.
055         * @param token  the Principal/Credential representation to be used during authentication for a corresponding subject.
056         * @return an empty AuthenticationInfo object that will populated with data from multiple realms.
057         * @throws AuthenticationException if the strategy implementation does not wish the Authentication attempt to execute.
058         */
059        AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token) throws AuthenticationException;
060    
061        /**
062         * Method invoked by the ModularAuthenticator just prior to the realm being consulted for account data,
063         * allowing pre-authentication-attempt logic for that realm only.
064         *
065         * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
066         * implementations will merely return the {@code aggregate} method argument if they don't have a need to
067         * manipulate it.
068         *
069         * @param realm     the realm that will be consulted for {@code AuthenticationInfo} for the specified {@code token}.
070         * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
071         * @param aggregate the aggregated AuthenticationInfo object being used across the multi-realm authentication attempt
072         * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
073         *         the {@code aggregate} method argument is the normal case if no special action needs to be taken.
074         * @throws org.apache.shiro.authc.AuthenticationException
075         *          an exception thrown by the Strategy implementation if it wishes the login
076         *          process for the associated subject (user) to stop immediately.
077         */
078        AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
079    
080        /**
081         * Method invoked by the ModularAuthenticator just after the given realm has been consulted for authentication,
082         * allowing post-authentication-attempt logic for that realm only.
083         *
084         * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
085         * implementations will merge the {@code singleRealmInfo} into the {@code aggregateInfo} and
086         * just return the {@code aggregateInfo} for continued use throughout the authentication process.</p>
087         *
088         * @param realm           the realm that was just consulted for {@code AuthenticationInfo} for the given {@code token}.
089         * @param token           the {@code AuthenticationToken} submitted for the subject attempting system log-in.
090         * @param singleRealmInfo the info returned from a single realm.
091         * @param aggregateInfo   the aggregate info representing all realms in a multi-realm environment.
092         * @param t               the Throwable thrown by the Realm during the attempt, or {@code null} if the method returned normally.
093         * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
094         *         the {@code aggregateAccount} method argument is the normal case if no special action needs to be taken.
095         * @throws AuthenticationException an exception thrown by the Strategy implementation if it wishes the login process
096         *                                 for the associated subject (user) to stop immediately.
097         */
098        AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t)
099                throws AuthenticationException;
100    
101        /**
102         * Method invoked by the ModularAuthenticator signifying that all of its configured Realms have been consulted
103         * for account data, allowing post-proccessing after all realms have completed.
104         *
105         * <p>Returns the final AuthenticationInfo object that will be returned from the Authenticator to the authenticate() caller.
106         * This is most likely the aggregate AuthenticationInfo object that has been populated by many realms, but the actual return value is
107         * always up to the implementation.
108         *
109         * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
110         * @param aggregate the aggregate {@code AuthenticationInfo} instance populated by all realms during the log-in attempt.
111         * @return the final {@code AuthenticationInfo} object to return to the Authenticator.authenticate() caller.
112         * @throws AuthenticationException if the Strategy implementation wishes to fail the authentication attempt.
113         */
114        AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
115    }