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.authc.MergableAuthenticationInfo;
25 import org.apache.shiro.authc.SimpleAuthenticationInfo;
26 import org.apache.shiro.realm.Realm;
27
28 import java.util.Collection;
29
30
31 /**
32 * Abstract base implementation for Shiro's concrete <code>AuthenticationStrategy</code>
33 * implementations.
34 *
35 * @since 0.9
36 */
37 public abstract class AbstractAuthenticationStrategy implements AuthenticationStrategy {
38
39 /**
40 * Simply returns <code>new {@link org.apache.shiro.authc.SimpleAuthenticationInfo SimpleAuthenticationInfo}();</code>,
41 * which supports
42 * aggregating account data across realms.
43 */
44 public AuthenticationInfo beforeAllAttempts(Collection<? extends Realm> realms, AuthenticationToken token)
45 throws AuthenticationException {
46 return new SimpleAuthenticationInfo();
47 }
48
49 /**
50 * Simply returns the <code>aggregate</code> method argument, without modification.
51 */
52 public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate)
53 throws AuthenticationException {
54 return aggregate;
55 }
56
57 /**
58 * Base implementation that will aggregate the specified <code>singleRealmInfo</code> into the
59 * <code>aggregateInfo</code> and then returns the aggregate. Can be overridden by subclasses for custom behavior.
60 */
61 public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token,
62 AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo,
63 Throwable t) throws AuthenticationException {
64 AuthenticationInfo info;
65 if (singleRealmInfo == null) {
66 info = aggregateInfo;
67 } else {
68 if (aggregateInfo == null) {
69 info = singleRealmInfo;
70 } else {
71 info = merge(singleRealmInfo, aggregateInfo);
72 }
73 }
74
75 return info;
76 }
77
78 /**
79 * Merges the specified <code>info</code> argument into the <code>aggregate</code> argument and then returns an
80 * aggregate for continued use throughout the login process.
81 * <p/>
82 * This implementation merely checks to see if the specified <code>aggregate</code> argument is an instance of
83 * {@link org.apache.shiro.authc.MergableAuthenticationInfo MergableAuthenticationInfo}, and if so, calls
84 * <code>aggregate.merge(info)</code> If it is <em>not</em> an instance of
85 * <code>MergableAuthenticationInfo</code>, an {@link IllegalArgumentException IllegalArgumentException} is thrown.
86 * Can be overridden by subclasses for custom merging behavior if implementing the
87 * {@link org.apache.shiro.authc.MergableAuthenticationInfo MergableAuthenticationInfo} is not desired for some reason.
88 */
89 protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {
90 if (aggregate instanceof MergableAuthenticationInfo) {
91 ((MergableAuthenticationInfo) aggregate).merge(info);
92 return aggregate;
93 } else {
94 throw new IllegalArgumentException("Attempt to merge authentication info from multiple realms, but aggregate "
95 + "AuthenticationInfo is not of type MergableAuthenticationInfo.");
96 }
97 }
98
99 /**
100 * Simply returns the <code>aggregate</code> argument without modification. Can be overridden for custom behavior.
101 */
102 public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate)
103 throws AuthenticationException {
104 return aggregate;
105 }
106 }