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;
020
021 import org.apache.shiro.subject.MutablePrincipalCollection;
022 import org.apache.shiro.subject.PrincipalCollection;
023 import org.apache.shiro.subject.SimplePrincipalCollection;
024
025 import java.util.Collection;
026 import java.util.HashSet;
027 import java.util.Set;
028
029
030 /**
031 * Simple implementation of the {@link org.apache.shiro.authc.MergableAuthenticationInfo} interface that holds the principals and
032 * credentials.
033 *
034 * @author Jeremy Haile
035 * @author Les Hazlewood
036 * @see org.apache.shiro.realm.AuthenticatingRealm
037 * @since 0.9
038 */
039 public class SimpleAuthenticationInfo implements MergableAuthenticationInfo {
040
041 /**
042 * The principals identifying the account associated with this AuthenticationInfo instance.
043 */
044 protected PrincipalCollection principals;
045 /**
046 * The credentials verifying the account principals.
047 */
048 protected Object credentials;
049
050 /**
051 * Default no-argument constructor.
052 */
053 public SimpleAuthenticationInfo() {
054 }
055
056 /**
057 * Constructor that takes in a single 'primary' principal of the account and its corresponding credentials,
058 * associated with the specified realm.
059 * <p/>
060 * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based
061 * on the <code>principal</code> and <code>realmName</code> argument.
062 *
063 * @param principal the 'primary' principal associated with the specified realm.
064 * @param credentials the credentials that verify the given principal.
065 * @param realmName the realm from where the principal and credentials were acquired.
066 */
067 public SimpleAuthenticationInfo(Object principal, Object credentials, String realmName) {
068 this.principals = new SimplePrincipalCollection(principal, realmName);
069 this.credentials = credentials;
070 }
071
072 /**
073 * Constructor that takes in an account's identifying principal(s) and its corresponding credentials that verify
074 * the principals.
075 *
076 * @param principals a Realm's account's identifying principal(s)
077 * @param credentials the accounts corresponding principals that verify the principals.
078 */
079 public SimpleAuthenticationInfo(PrincipalCollection principals, Object credentials) {
080 this.principals = new SimplePrincipalCollection(principals);
081 this.credentials = credentials;
082 }
083
084
085 public PrincipalCollection getPrincipals() {
086 return principals;
087 }
088
089 /**
090 * Sets the identifying principal(s) represented by this instance.
091 *
092 * @param principals the indentifying attributes of the corresponding Realm account.
093 */
094 public void setPrincipals(PrincipalCollection principals) {
095 this.principals = principals;
096 }
097
098 public Object getCredentials() {
099 return credentials;
100 }
101
102 /**
103 * Sets the credentials that verify the principals/identity of the associated Realm account.
104 *
105 * @param credentials attribute(s) that verify the account's identity/principals, such as a password or private key.
106 */
107 public void setCredentials(Object credentials) {
108 this.credentials = credentials;
109 }
110
111 /**
112 * Takes the specified <code>info</code> argument and adds its principals and credentials into this instance.
113 *
114 * @param info the <code>AuthenticationInfo</code> to add into this instance.
115 */
116 @SuppressWarnings("unchecked")
117 public void merge(AuthenticationInfo info) {
118 if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) {
119 return;
120 }
121
122 if (this.principals == null) {
123 this.principals = info.getPrincipals();
124 } else {
125 if (!(this.principals instanceof MutablePrincipalCollection)) {
126 this.principals = new SimplePrincipalCollection(this.principals);
127 }
128 ((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals());
129 }
130
131 Object thisCredentials = getCredentials();
132 Object otherCredentials = info.getCredentials();
133
134 if (otherCredentials == null) {
135 return;
136 }
137
138 if (thisCredentials == null) {
139 this.credentials = otherCredentials;
140 return;
141 }
142
143 if (!(thisCredentials instanceof Collection)) {
144 Set newSet = new HashSet();
145 newSet.add(thisCredentials);
146 setCredentials(newSet);
147 }
148
149 // At this point, the credentials should be a collection
150 Collection credentialCollection = (Collection) getCredentials();
151 if (otherCredentials instanceof Collection) {
152 credentialCollection.addAll((Collection) otherCredentials);
153 } else {
154 credentialCollection.add(otherCredentials);
155 }
156 }
157
158 /**
159 * Returns <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
160 * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
161 *
162 * @param o the object to compare for equality.
163 * @return <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
164 * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
165 */
166 public boolean equals(Object o) {
167 if (this == o) return true;
168 if (!(o instanceof SimpleAuthenticationInfo)) return false;
169
170 SimpleAuthenticationInfo that = (SimpleAuthenticationInfo) o;
171
172 //noinspection RedundantIfStatement
173 if (principals != null ? !principals.equals(that.principals) : that.principals != null) return false;
174
175 return true;
176 }
177
178 /**
179 * Returns the hashcode of the internal {@link #getPrincipals() principals} instance.
180 *
181 * @return the hashcode of the internal {@link #getPrincipals() principals} instance.
182 */
183 public int hashCode() {
184 return (principals != null ? principals.hashCode() : 0);
185 }
186
187 /**
188 * Simple implementation that merely returns <code>{@link #getPrincipals() principals}.toString()</code>
189 *
190 * @return <code>{@link #getPrincipals() principals}.toString()</code>
191 */
192 public String toString() {
193 return principals.toString();
194 }
195
196 }