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 module hunt.shiro.authc.pam.AuthenticationStrategy;
20 
21 
22 import hunt.shiro.Exceptions;
23 import hunt.shiro.authc.AuthenticationInfo;
24 import hunt.shiro.authc.AuthenticationToken;
25 import hunt.shiro.realm.Realm;
26 
27 import hunt.collection;
28 
29 
30 /**
31  * A {@code AuthenticationStrategy} implementation assists the {@link ModularRealmAuthenticator} during the
32  * log-in process in a pluggable realm (PAM) environment.
33  *
34  * <p>The {@code ModularRealmAuthenticator} will consult implementations of this interface on what to do during each
35  * interaction with the configured Realms.  This allows a pluggable strategy of whether or not an authentication
36  * attempt must be successful for all realms, only 1 or more realms, no realms, etc.
37  *
38  * @see AllSuccessfulStrategy
39  * @see AtLeastOneSuccessfulStrategy
40  * @see FirstSuccessfulStrategy
41  */
42 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(Realm[] realms, AuthenticationToken token);
60 
61     /**
62      * Method invoked by the ModularAuthenticator just prior to the realm being consulted for account data,
63      * allowing pre-authentication-attempt logic for that realm only.
64      *
65      * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
66      * implementations will merely return the {@code aggregate} method argument if they don't have a need to
67      * manipulate it.
68      *
69      * @param realm     the realm that will be consulted for {@code AuthenticationInfo} for the specified {@code token}.
70      * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
71      * @param aggregate the aggregated AuthenticationInfo object being used across the multi-realm authentication attempt
72      * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
73      *         the {@code aggregate} method argument is the normal case if no special action needs to be taken.
74      * @throws hunt.shiro.authc.AuthenticationException
75      *          an exception thrown by the Strategy implementation if it wishes the login
76      *          process for the associated subject (user) to stop immediately.
77      */
78     AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate);
79 
80     /**
81      * Method invoked by the ModularAuthenticator just after the given realm has been consulted for authentication,
82      * allowing post-authentication-attempt logic for that realm only.
83      *
84      * <p>This method returns an {@code AuthenticationInfo} object that will be used for further interaction with realms.  Most
85      * implementations will merge the {@code singleRealmInfo} into the {@code aggregateInfo} and
86      * just return the {@code aggregateInfo} for continued use throughout the authentication process.</p>
87      *
88      * @param realm           the realm that was just consulted for {@code AuthenticationInfo} for the given {@code token}.
89      * @param token           the {@code AuthenticationToken} submitted for the subject attempting system log-in.
90      * @param singleRealmInfo the info returned from a single realm.
91      * @param aggregateInfo   the aggregate info representing all realms in a multi-realm environment.
92      * @param t               the Throwable thrown by the Realm during the attempt, or {@code null} if the method returned normally.
93      * @return the AuthenticationInfo object that will be presented to further realms in the authentication process - returning
94      *         the {@code aggregateAccount} method argument is the normal case if no special action needs to be taken.
95      * @throws AuthenticationException an exception thrown by the Strategy implementation if it wishes the login process
96      *                                 for the associated subject (user) to stop immediately.
97      */
98     AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t);
99 
100     /**
101      * Method invoked by the ModularAuthenticator signifying that all of its configured Realms have been consulted
102      * for account data, allowing post-processing after all realms have completed.
103      *
104      * <p>Returns the final AuthenticationInfo object that will be returned from the Authenticator to the authenticate() caller.
105      * This is most likely the aggregate AuthenticationInfo object that has been populated by many realms, but the actual return value is
106      * always up to the implementation.
107      *
108      * @param token     the {@code AuthenticationToken} submitted for the subject attempting system log-in.
109      * @param aggregate the aggregate {@code AuthenticationInfo} instance populated by all realms during the log-in attempt.
110      * @return the final {@code AuthenticationInfo} object to return to the Authenticator.authenticate() caller.
111      * @throws AuthenticationException if the Strategy implementation wishes to fail the authentication attempt.
112      */
113     AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate);
114 }