Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
SimpleAuthenticationInfo |
|
| 2.466666666666667;2.467 |
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; | |
20 | ||
21 | import org.apache.shiro.subject.MutablePrincipalCollection; | |
22 | import org.apache.shiro.subject.PrincipalCollection; | |
23 | import org.apache.shiro.subject.SimplePrincipalCollection; | |
24 | import org.apache.shiro.util.ByteSource; | |
25 | ||
26 | import java.util.Collection; | |
27 | import java.util.HashSet; | |
28 | import java.util.Set; | |
29 | ||
30 | ||
31 | /** | |
32 | * Simple implementation of the {@link org.apache.shiro.authc.MergableAuthenticationInfo} interface that holds the principals and | |
33 | * credentials. | |
34 | * | |
35 | * @see org.apache.shiro.realm.AuthenticatingRealm | |
36 | * @since 0.9 | |
37 | */ | |
38 | public class SimpleAuthenticationInfo implements MergableAuthenticationInfo, SaltedAuthenticationInfo { | |
39 | ||
40 | /** | |
41 | * The principals identifying the account associated with this AuthenticationInfo instance. | |
42 | */ | |
43 | protected PrincipalCollection principals; | |
44 | /** | |
45 | * The credentials verifying the account principals. | |
46 | */ | |
47 | protected Object credentials; | |
48 | ||
49 | /** | |
50 | * Any salt used in hashing the credentials. | |
51 | * | |
52 | * @since 1.1 | |
53 | */ | |
54 | protected ByteSource credentialsSalt; | |
55 | ||
56 | /** | |
57 | * Default no-argument constructor. | |
58 | */ | |
59 | 5 | public SimpleAuthenticationInfo() { |
60 | 5 | } |
61 | ||
62 | /** | |
63 | * Constructor that takes in a single 'primary' principal of the account and its corresponding credentials, | |
64 | * associated with the specified realm. | |
65 | * <p/> | |
66 | * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based | |
67 | * on the {@code principal} and {@code realmName} argument. | |
68 | * | |
69 | * @param principal the 'primary' principal associated with the specified realm. | |
70 | * @param credentials the credentials that verify the given principal. | |
71 | * @param realmName the realm from where the principal and credentials were acquired. | |
72 | */ | |
73 | 29 | public SimpleAuthenticationInfo(Object principal, Object credentials, String realmName) { |
74 | 29 | this.principals = new SimplePrincipalCollection(principal, realmName); |
75 | 29 | this.credentials = credentials; |
76 | 29 | } |
77 | ||
78 | /** | |
79 | * Constructor that takes in a single 'primary' principal of the account, its corresponding hashed credentials, | |
80 | * the salt used to hash the credentials, and the name of the realm to associate with the principals. | |
81 | * <p/> | |
82 | * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based | |
83 | * on the <code>principal</code> and <code>realmName</code> argument. | |
84 | * | |
85 | * @param principal the 'primary' principal associated with the specified realm. | |
86 | * @param hashedCredentials the hashed credentials that verify the given principal. | |
87 | * @param credentialsSalt the salt used when hashing the given hashedCredentials | |
88 | * @param realmName the realm from where the principal and credentials were acquired. | |
89 | * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher | |
90 | * @since 1.1 | |
91 | */ | |
92 | 1 | public SimpleAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName) { |
93 | 1 | this.principals = new SimplePrincipalCollection(principal, realmName); |
94 | 1 | this.credentials = hashedCredentials; |
95 | 1 | this.credentialsSalt = credentialsSalt; |
96 | 1 | } |
97 | ||
98 | /** | |
99 | * Constructor that takes in an account's identifying principal(s) and its corresponding credentials that verify | |
100 | * the principals. | |
101 | * | |
102 | * @param principals a Realm's account's identifying principal(s) | |
103 | * @param credentials the accounts corresponding principals that verify the principals. | |
104 | */ | |
105 | 40 | public SimpleAuthenticationInfo(PrincipalCollection principals, Object credentials) { |
106 | 40 | this.principals = new SimplePrincipalCollection(principals); |
107 | 40 | this.credentials = credentials; |
108 | 40 | } |
109 | ||
110 | /** | |
111 | * Constructor that takes in an account's identifying principal(s), hashed credentials used to verify the | |
112 | * principals, and the salt used when hashing the credentials. | |
113 | * | |
114 | * @param principals a Realm's account's identifying principal(s) | |
115 | * @param hashedCredentials the hashed credentials that verify the principals. | |
116 | * @param credentialsSalt the salt used when hashing the hashedCredentials. | |
117 | * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher | |
118 | * @since 1.1 | |
119 | */ | |
120 | 0 | public SimpleAuthenticationInfo(PrincipalCollection principals, Object hashedCredentials, ByteSource credentialsSalt) { |
121 | 0 | this.principals = new SimplePrincipalCollection(principals); |
122 | 0 | this.credentials = hashedCredentials; |
123 | 0 | this.credentialsSalt = credentialsSalt; |
124 | 0 | } |
125 | ||
126 | ||
127 | public PrincipalCollection getPrincipals() { | |
128 | 173 | return principals; |
129 | } | |
130 | ||
131 | /** | |
132 | * Sets the identifying principal(s) represented by this instance. | |
133 | * | |
134 | * @param principals the indentifying attributes of the corresponding Realm account. | |
135 | */ | |
136 | public void setPrincipals(PrincipalCollection principals) { | |
137 | 2 | this.principals = principals; |
138 | 2 | } |
139 | ||
140 | public Object getCredentials() { | |
141 | 31 | return credentials; |
142 | } | |
143 | ||
144 | /** | |
145 | * Sets the credentials that verify the principals/identity of the associated Realm account. | |
146 | * | |
147 | * @param credentials attribute(s) that verify the account's identity/principals, such as a password or private key. | |
148 | */ | |
149 | public void setCredentials(Object credentials) { | |
150 | 37 | this.credentials = credentials; |
151 | 37 | } |
152 | ||
153 | /** | |
154 | * Returns the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not | |
155 | * hashed at all. | |
156 | * <p/> | |
157 | * Note that this attribute is <em>NOT</em> handled in the | |
158 | * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each | |
159 | * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further | |
160 | * use for salts. Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario. | |
161 | * | |
162 | * @return the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not | |
163 | * hashed at all. | |
164 | * @since 1.1 | |
165 | */ | |
166 | public ByteSource getCredentialsSalt() { | |
167 | 20 | return credentialsSalt; |
168 | } | |
169 | ||
170 | /** | |
171 | * Sets the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not | |
172 | * hashed at all. | |
173 | * <p/> | |
174 | * Note that this attribute is <em>NOT</em> handled in the | |
175 | * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each | |
176 | * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further | |
177 | * use for salts. Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario. | |
178 | * | |
179 | * @param salt the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not | |
180 | * hashed at all. | |
181 | * @since 1.1 | |
182 | */ | |
183 | public void setCredentialsSalt(ByteSource salt) { | |
184 | 4 | this.credentialsSalt = salt; |
185 | 4 | } |
186 | ||
187 | /** | |
188 | * Takes the specified <code>info</code> argument and adds its principals and credentials into this instance. | |
189 | * | |
190 | * @param info the <code>AuthenticationInfo</code> to add into this instance. | |
191 | */ | |
192 | @SuppressWarnings("unchecked") | |
193 | public void merge(AuthenticationInfo info) { | |
194 | 3 | if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) { |
195 | 1 | return; |
196 | } | |
197 | ||
198 | 2 | if (this.principals == null) { |
199 | 1 | this.principals = info.getPrincipals(); |
200 | } else { | |
201 | 1 | if (!(this.principals instanceof MutablePrincipalCollection)) { |
202 | 1 | this.principals = new SimplePrincipalCollection(this.principals); |
203 | } | |
204 | 1 | ((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals()); |
205 | } | |
206 | ||
207 | //only mess with a salt value if we don't have one yet. It doesn't make sense | |
208 | //to merge salt values from different realms because a salt is used only within | |
209 | //the realm's credential matching process. But if the current instance's salt | |
210 | //is null, then it can't hurt to pull in a non-null value if one exists. | |
211 | // | |
212 | //since 1.1: | |
213 | 2 | if (this.credentialsSalt == null && info instanceof SaltedAuthenticationInfo) { |
214 | 2 | this.credentialsSalt = ((SaltedAuthenticationInfo) info).getCredentialsSalt(); |
215 | } | |
216 | ||
217 | 2 | Object thisCredentials = getCredentials(); |
218 | 2 | Object otherCredentials = info.getCredentials(); |
219 | ||
220 | 2 | if (otherCredentials == null) { |
221 | 0 | return; |
222 | } | |
223 | ||
224 | 2 | if (thisCredentials == null) { |
225 | 2 | this.credentials = otherCredentials; |
226 | 2 | return; |
227 | } | |
228 | ||
229 | 0 | if (!(thisCredentials instanceof Collection)) { |
230 | 0 | Set newSet = new HashSet(); |
231 | 0 | newSet.add(thisCredentials); |
232 | 0 | setCredentials(newSet); |
233 | } | |
234 | ||
235 | // At this point, the credentials should be a collection | |
236 | 0 | Collection credentialCollection = (Collection) getCredentials(); |
237 | 0 | if (otherCredentials instanceof Collection) { |
238 | 0 | credentialCollection.addAll((Collection) otherCredentials); |
239 | } else { | |
240 | 0 | credentialCollection.add(otherCredentials); |
241 | } | |
242 | 0 | } |
243 | ||
244 | /** | |
245 | * Returns <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and | |
246 | * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise. | |
247 | * | |
248 | * @param o the object to compare for equality. | |
249 | * @return <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and | |
250 | * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise. | |
251 | */ | |
252 | public boolean equals(Object o) { | |
253 | 1 | if (this == o) return true; |
254 | 0 | if (!(o instanceof SimpleAuthenticationInfo)) return false; |
255 | ||
256 | 0 | SimpleAuthenticationInfo that = (SimpleAuthenticationInfo) o; |
257 | ||
258 | //noinspection RedundantIfStatement | |
259 | 0 | if (principals != null ? !principals.equals(that.principals) : that.principals != null) return false; |
260 | ||
261 | 0 | return true; |
262 | } | |
263 | ||
264 | /** | |
265 | * Returns the hashcode of the internal {@link #getPrincipals() principals} instance. | |
266 | * | |
267 | * @return the hashcode of the internal {@link #getPrincipals() principals} instance. | |
268 | */ | |
269 | public int hashCode() { | |
270 | 0 | return (principals != null ? principals.hashCode() : 0); |
271 | } | |
272 | ||
273 | /** | |
274 | * Simple implementation that merely returns <code>{@link #getPrincipals() principals}.toString()</code> | |
275 | * | |
276 | * @return <code>{@link #getPrincipals() principals}.toString()</code> | |
277 | */ | |
278 | public String toString() { | |
279 | 42 | return principals.toString(); |
280 | } | |
281 | ||
282 | } |