View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.authc.pam;
20  
21  import org.apache.shiro.authc.AuthenticationException;
22  import org.apache.shiro.authc.AuthenticationInfo;
23  import org.apache.shiro.authc.AuthenticationToken;
24  import org.apache.shiro.realm.Realm;
25  
26  import java.util.Collection;
27  
28  
29  /**
30   * A {@code AuthenticationStrategy} implementation assists the {@link ModularRealmAuthenticator} during the
31   * log-in process in a pluggable realm (PAM) environment.
32   *
33   * <p>The {@code ModularRealmAuthenticator} will consult implementations of this interface on what to do during each
34   * interaction with the configured Realms.  This allows a pluggable strategy of whether or not an authentication
35   * attempt must be successful for all realms, only 1 or more realms, no realms, etc.
36   *
37   * @see AllSuccessfulStrategy
38   * @see AtLeastOneSuccessfulStrategy
39   * @see FirstSuccessfulStrategy
40   * @since 0.2
41   */
42  public interface AuthenticationStrategy {
43  
44      /**
45       * Method invoked by the ModularAuthenticator signifying that the authentication process is about to begin for the
46       * specified {@code token} - called before any {@code Realm} is actually invoked.
47       *
48       * <p>The {@code AuthenticationInfo} object returned from this method is essentially an empty place holder for
49       * aggregating account data across multiple realms.  It should be populated by the strategy implementation over the
50       * course of authentication attempts across the multiple realms.  It will be passed into the
51       * {@link #beforeAttempt} calls, allowing inspection of the aggregated account data up to that point in the
52       * multi-realm authentication, allowing any logic to be executed accordingly.
53       *
54       * @param realms the Realms that will be consulted during the authentication process for the specified token.
55       * @param token  the Principal/Credential representation to be used during authentication for a corresponding subject.
56       * @return an empty AuthenticationInfo object that will populated with data from multiple realms.
57       * @throws AuthenticationException if the strategy implementation does not wish the Authentication attempt to execute.
58       */
59      AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token)
60              throws AuthenticationException;
61  
62      /**
63       * Method invoked by the ModularAuthenticator just prior to the realm being consulted for account data,
64       * allowing pre-authentication-attempt logic for that realm only.
65       *
66       * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
67       * implementations will merely return the {@code aggregate} method argument if they don't have a need to
68       * manipulate it.
69       *
70       * @param realm     the realm that will be consulted for {@code AuthenticationInfo} for the specified {@code token}.
71       * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
72       * @param aggregate the aggregated AuthenticationInfo object being used across the multi-realm authentication attempt
73       * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
74       * the {@code aggregate} method argument is the normal case if no special action needs to be taken.
75       * @throws org.apache.shiro.authc.AuthenticationException
76       *      an exception thrown by the Strategy implementation if it wishes the login process
77       * for the associated subject (user) to stop immediately.
78       */
79      AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate)
80              throws AuthenticationException;
81  
82      /**
83       * Method invoked by the ModularAuthenticator just after the given realm has been consulted for authentication,
84       * allowing post-authentication-attempt logic for that realm only.
85       *
86       * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
87       * implementations will merge the {@code singleRealmInfo} into the {@code aggregateInfo} and
88       * just return the {@code aggregateInfo} for continued use throughout the authentication process.</p>
89       *
90       * @param realm           the realm that was just consulted for {@code AuthenticationInfo} for the given {@code token}.
91       * @param token           the {@code AuthenticationToken} submitted for the subject attempting system log-in.
92       * @param singleRealmInfo the info returned from a single realm.
93       * @param aggregateInfo   the aggregate info representing all realms in a multi-realm environment.
94       * @param t               the Throwable thrown by the Realm during the attempt,
95       *                          or {@code null} if the method returned normally.
96       * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
97       * the {@code aggregateAccount} method argument is the normal case if no special action needs to be taken.
98       * @throws AuthenticationException an exception thrown by the Strategy implementation if it wishes the login process
99       *                                 for the associated subject (user) to stop immediately.
100      */
101     AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token,
102                                     AuthenticationInfo singleRealmInfo,
103                                     AuthenticationInfo aggregateInfo, Throwable t)
104             throws AuthenticationException;
105 
106     /**
107      * Method invoked by the ModularAuthenticator signifying that all of its configured Realms have been consulted
108      * for account data, allowing post-processing after all realms have completed.
109      *
110      * <p>Returns the final AuthenticationInfo object that will be returned from the Authenticator to the authenticate() caller.
111      * This is most likely the aggregate AuthenticationInfo object that has been populated by many realms,
112      * but the actual return value is
113      * always up to the implementation.
114      *
115      * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
116      * @param aggregate the aggregate {@code AuthenticationInfo} instance populated by all realms during the log-in attempt.
117      * @return the final {@code AuthenticationInfo} object to return to the Authenticator.authenticate() caller.
118      * @throws AuthenticationException if the Strategy implementation wishes to fail the authentication attempt.
119      */
120     AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;
121 }