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 */ 019package org.apache.shiro.authc; 020 021import org.apache.shiro.authz.Permission; 022import org.apache.shiro.authz.SimpleAuthorizationInfo; 023import org.apache.shiro.subject.PrincipalCollection; 024import org.apache.shiro.subject.SimplePrincipalCollection; 025import org.apache.shiro.lang.util.ByteSource; 026 027import java.io.Serializable; 028import java.util.Collection; 029import java.util.Set; 030 031 032/** 033 * Simple implementation of the {@link org.apache.shiro.authc.Account} interface that 034 * contains principal and credential and authorization information (roles and permissions) as instance variables and 035 * exposes them via getters and setters using standard JavaBean notation. 036 * 037 * @since 0.1 038 */ 039public class SimpleAccount implements Account, MergableAuthenticationInfo, SaltedAuthenticationInfo, Serializable { 040 041 /*-------------------------------------------- 042 | I N S T A N C E V A R I A B L E S | 043 ============================================*/ 044 /** 045 * The authentication information (principals and credentials) for this account. 046 */ 047 private SimpleAuthenticationInfo authcInfo; 048 049 /** 050 * The authorization information for this account. 051 */ 052 private SimpleAuthorizationInfo authzInfo; 053 054 /** 055 * Indicates this account is locked. This isn't honored by all <tt>Realms</tt> but is honored by 056 * {@link org.apache.shiro.realm.SimpleAccountRealm}. 057 */ 058 private boolean locked; 059 060 /** 061 * Indicates credentials on this account are expired. This isn't honored by all <tt>Realms</tt> but is honored by 062 * {@link org.apache.shiro.realm.SimpleAccountRealm}. 063 */ 064 private boolean credentialsExpired; 065 066 /*-------------------------------------------- 067 | C O N S T R U C T O R S | 068 ============================================*/ 069 070 /** 071 * Default no-argument constructor. 072 */ 073 public SimpleAccount() { 074 } 075 076 /** 077 * Constructs a SimpleAccount instance for the specified realm with the given principals and credentials. 078 * 079 * @param principal the 'primary' identifying attribute of the account, for example, a user id or username. 080 * @param credentials the credentials that verify identity for the account 081 * @param realmName the name of the realm that accesses this account data 082 */ 083 public SimpleAccount(Object principal, Object credentials, String realmName) { 084 this(principal instanceof PrincipalCollection 085 ? (PrincipalCollection) principal : new SimplePrincipalCollection(principal, realmName), credentials); 086 } 087 088 /** 089 * Constructs a SimpleAccount instance for the specified realm with the given principals, hashedCredentials and 090 * credentials salt used when hashing the credentials. 091 * 092 * @param principal the 'primary' identifying attribute of the account, for example, a user id or username. 093 * @param hashedCredentials the credentials that verify identity for the account 094 * @param credentialsSalt the salt used when hashing the credentials 095 * @param realmName the name of the realm that accesses this account data 096 * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher 097 * @since 1.1 098 */ 099 public SimpleAccount(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName) { 100 this(principal instanceof PrincipalCollection ? (PrincipalCollection) principal 101 : new SimplePrincipalCollection(principal, realmName), 102 hashedCredentials, credentialsSalt); 103 } 104 105 /** 106 * Constructs a SimpleAccount instance for the specified realm with the given principals and credentials. 107 * 108 * @param principals the identifying attributes of the account, at least one of which should be considered the 109 * account's 'primary' identifying attribute, for example, a user id or username. 110 * @param credentials the credentials that verify identity for the account 111 * @param realmName the name of the realm that accesses this account data 112 */ 113 public SimpleAccount(Collection principals, Object credentials, String realmName) { 114 this(new SimplePrincipalCollection(principals, realmName), credentials); 115 } 116 117 /** 118 * Constructs a SimpleAccount instance for the specified principals and credentials. 119 * 120 * @param principals the identifying attributes of the account, at least one of which should be considered the 121 * account's 'primary' identifying attribute, for example, a user id or username. 122 * @param credentials the credentials that verify identity for the account 123 */ 124 public SimpleAccount(PrincipalCollection principals, Object credentials) { 125 this.authcInfo = new SimpleAuthenticationInfo(principals, credentials); 126 this.authzInfo = new SimpleAuthorizationInfo(); 127 } 128 129 /** 130 * Constructs a SimpleAccount instance for the specified principals and credentials. 131 * 132 * @param principals the identifying attributes of the account, at least one of which should be considered the 133 * account's 'primary' identifying attribute, for example, a user id or username. 134 * @param hashedCredentials the hashed credentials that verify identity for the account 135 * @param credentialsSalt the salt used when hashing the credentials 136 * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher 137 * @since 1.1 138 */ 139 public SimpleAccount(PrincipalCollection principals, Object hashedCredentials, ByteSource credentialsSalt) { 140 this.authcInfo = new SimpleAuthenticationInfo(principals, hashedCredentials, credentialsSalt); 141 this.authzInfo = new SimpleAuthorizationInfo(); 142 } 143 144 /** 145 * Constructs a SimpleAccount instance for the specified principals and credentials, with the assigned roles. 146 * 147 * @param principals the identifying attributes of the account, at least one of which should be considered the 148 * account's 'primary' identifying attribute, for example, a user id or username. 149 * @param credentials the credentials that verify identity for the account 150 * @param roles the names of the roles assigned to this account. 151 */ 152 public SimpleAccount(PrincipalCollection principals, Object credentials, Set<String> roles) { 153 this.authcInfo = new SimpleAuthenticationInfo(principals, credentials); 154 this.authzInfo = new SimpleAuthorizationInfo(roles); 155 } 156 157 /** 158 * Constructs a SimpleAccount instance for the specified realm with the given principal and credentials, with the 159 * the assigned roles and permissions. 160 * 161 * @param principal the 'primary' identifying attributes of the account, for example, a user id or username. 162 * @param credentials the credentials that verify identity for the account 163 * @param realmName the name of the realm that accesses this account data 164 * @param roleNames the names of the roles assigned to this account. 165 * @param permissions the permissions assigned to this account directly (not those assigned to any of the realms). 166 */ 167 public SimpleAccount(Object principal, Object credentials, String realmName, 168 Set<String> roleNames, Set<Permission> permissions) { 169 this.authcInfo = new SimpleAuthenticationInfo(new SimplePrincipalCollection(principal, realmName), credentials); 170 this.authzInfo = new SimpleAuthorizationInfo(roleNames); 171 this.authzInfo.setObjectPermissions(permissions); 172 } 173 174 /** 175 * Constructs a SimpleAccount instance for the specified realm with the given principals and credentials, with the 176 * the assigned roles and permissions. 177 * 178 * @param principals the identifying attributes of the account, at least one of which should be considered the 179 * account's 'primary' identifying attribute, for example, a user id or username. 180 * @param credentials the credentials that verify identity for the account 181 * @param realmName the name of the realm that accesses this account data 182 * @param roleNames the names of the roles assigned to this account. 183 * @param permissions the permissions assigned to this account directly (not those assigned to any of the realms). 184 */ 185 186 public SimpleAccount(Collection principals, Object credentials, String realmName, 187 Set<String> roleNames, Set<Permission> permissions) { 188 this.authcInfo = new SimpleAuthenticationInfo(new SimplePrincipalCollection(principals, realmName), credentials); 189 this.authzInfo = new SimpleAuthorizationInfo(roleNames); 190 this.authzInfo.setObjectPermissions(permissions); 191 } 192 193 /** 194 * Constructs a SimpleAccount instance from the given principals and credentials, with the 195 * the assigned roles and permissions. 196 * 197 * @param principals the identifying attributes of the account, at least one of which should be considered the 198 * account's 'primary' identifying attribute, for example, a user id or username. 199 * @param credentials the credentials that verify identity for the account 200 * @param roleNames the names of the roles assigned to this account. 201 * @param permissions the permissions assigned to this account directly (not those assigned to any of the realms). 202 */ 203 public SimpleAccount(PrincipalCollection principals, Object credentials, Set<String> roleNames, Set<Permission> permissions) { 204 this.authcInfo = new SimpleAuthenticationInfo(principals, credentials); 205 this.authzInfo = new SimpleAuthorizationInfo(roleNames); 206 this.authzInfo.setObjectPermissions(permissions); 207 } 208 209 /*-------------------------------------------- 210 | A C C E S S O R S / M O D I F I E R S | 211 ============================================*/ 212 213 /** 214 * Returns the principals, aka the identifying attributes (username, user id, first name, last name, etc.) of this 215 * Account. 216 * 217 * @return all the principals, aka the identifying attributes, of this Account. 218 */ 219 public PrincipalCollection getPrincipals() { 220 return authcInfo.getPrincipals(); 221 } 222 223 /** 224 * Sets the principals, aka the identifying attributes (username, user id, first name, last name, etc.) of this 225 * Account. 226 * 227 * @param principals all the principals, aka the identifying attributes, of this Account. 228 * @see Account#getPrincipals() 229 */ 230 public void setPrincipals(PrincipalCollection principals) { 231 this.authcInfo.setPrincipals(principals); 232 } 233 234 235 /** 236 * Simply returns <code>this.authcInfo.getCredentials</code>. The <code>authcInfo</code> attribute is constructed 237 * via the constructors to wrap the input arguments. 238 * 239 * @return this Account's credentials. 240 */ 241 public Object getCredentials() { 242 return authcInfo.getCredentials(); 243 } 244 245 /** 246 * Sets this Account's credentials that verify one or more of the Account's 247 * {@link #getPrincipals() principals}, such as a password or private key. 248 * 249 * @param credentials the credentials associated with this Account that verify one or more of the Account principals. 250 * @see org.apache.shiro.authc.Account#getCredentials() 251 */ 252 public void setCredentials(Object credentials) { 253 this.authcInfo.setCredentials(credentials); 254 } 255 256 /** 257 * Returns the salt used to hash this Account's credentials (e.g. for password hashing), or {@code null} if no salt 258 * was used or credentials were not hashed at all. 259 * 260 * @return the salt used to hash this Account's credentials (e.g. for password hashing), or {@code null} if no salt 261 * was used or credentials were not hashed at all. 262 * @since 1.1 263 */ 264 public ByteSource getCredentialsSalt() { 265 return this.authcInfo.getCredentialsSalt(); 266 } 267 268 /** 269 * Sets the salt to use to hash this Account's credentials (e.g. for password hashing), or {@code null} if no salt 270 * is used or credentials are not hashed at all. 271 * 272 * @param salt the salt to use to hash this Account's credentials (e.g. for password hashing), or {@code null} if no 273 * salt is used or credentials are not hashed at all. 274 * @since 1.1 275 */ 276 public void setCredentialsSalt(ByteSource salt) { 277 this.authcInfo.setCredentialsSalt(salt); 278 } 279 280 /** 281 * Returns <code>this.authzInfo.getRoles();</code> 282 * 283 * @return the Account's assigned roles. 284 */ 285 public Collection<String> getRoles() { 286 return authzInfo.getRoles(); 287 } 288 289 /** 290 * Sets the Account's assigned roles. Simply calls <code>this.authzInfo.setRoles(roles)</code>. 291 * 292 * @param roles the Account's assigned roles. 293 * @see Account#getRoles() 294 */ 295 public void setRoles(Set<String> roles) { 296 this.authzInfo.setRoles(roles); 297 } 298 299 /** 300 * Adds a role to this Account's set of assigned roles. Simply delegates to 301 * <code>this.authzInfo.addRole(role)</code>. 302 * 303 * @param role a role to assign to this Account. 304 */ 305 public void addRole(String role) { 306 this.authzInfo.addRole(role); 307 } 308 309 /** 310 * Adds one or more roles to this Account's set of assigned roles. Simply delegates to 311 * <code>this.authzInfo.addRoles(roles)</code>. 312 * 313 * @param roles one or more roles to assign to this Account. 314 */ 315 public void addRole(Collection<String> roles) { 316 this.authzInfo.addRoles(roles); 317 } 318 319 /** 320 * Returns all String-based permissions assigned to this Account. Simply delegates to 321 * <code>this.authzInfo.getStringPermissions()</code>. 322 * 323 * @return all String-based permissions assigned to this Account. 324 */ 325 public Collection<String> getStringPermissions() { 326 return authzInfo.getStringPermissions(); 327 } 328 329 /** 330 * Sets the String-based permissions assigned to this Account. Simply delegates to 331 * <code>this.authzInfo.setStringPermissions(permissions)</code>. 332 * 333 * @param permissions all String-based permissions assigned to this Account. 334 * @see org.apache.shiro.authc.Account#getStringPermissions() 335 */ 336 public void setStringPermissions(Set<String> permissions) { 337 this.authzInfo.setStringPermissions(permissions); 338 } 339 340 /** 341 * Assigns a String-based permission directly to this Account (not to any of its realms). 342 * 343 * @param permission the String-based permission to assign. 344 */ 345 public void addStringPermission(String permission) { 346 this.authzInfo.addStringPermission(permission); 347 } 348 349 /** 350 * Assigns one or more string-based permissions directly to this Account (not to any of its realms). 351 * 352 * @param permissions one or more String-based permissions to assign. 353 */ 354 public void addStringPermissions(Collection<String> permissions) { 355 this.authzInfo.addStringPermissions(permissions); 356 } 357 358 /** 359 * Returns all object-based permissions assigned directly to this Account (not any of its realms). 360 * 361 * @return all object-based permissions assigned directly to this Account (not any of its realms). 362 */ 363 public Collection<Permission> getObjectPermissions() { 364 return authzInfo.getObjectPermissions(); 365 } 366 367 /** 368 * Set al. object-based permissions assigned directly to this Account (not any of its realms). 369 * 370 * @param permissions the object-based permissions to assign directly to this Account. 371 */ 372 public void setObjectPermissions(Set<Permission> permissions) { 373 this.authzInfo.setObjectPermissions(permissions); 374 } 375 376 /** 377 * Assigns an object-based permission directly to this Account (not any of its realms). 378 * 379 * @param permission the object-based permission to assign directly to this Account (not any of its realms). 380 */ 381 public void addObjectPermission(Permission permission) { 382 this.authzInfo.addObjectPermission(permission); 383 } 384 385 /** 386 * Assigns one or more object-based permissions directly to this Account (not any of its realms). 387 * 388 * @param permissions one or more object-based permissions to assign directly to this Account (not any of its realms). 389 */ 390 public void addObjectPermissions(Collection<Permission> permissions) { 391 this.authzInfo.addObjectPermissions(permissions); 392 } 393 394 /** 395 * Returns <code>true</code> if this Account is locked and thus cannot be used to login, <code>false</code> otherwise. 396 * 397 * @return <code>true</code> if this Account is locked and thus cannot be used to login, <code>false</code> otherwise. 398 */ 399 public boolean isLocked() { 400 return locked; 401 } 402 403 /** 404 * Sets whether or not the account is locked and can be used to login. 405 * 406 * @param locked <code>true</code> if this Account is locked and thus cannot be used to login, <code>false</code> otherwise. 407 */ 408 public void setLocked(boolean locked) { 409 this.locked = locked; 410 } 411 412 /** 413 * Returns whether or not the Account's credentials are expired. This usually indicates that the Subject or an application 414 * administrator would need to change the credentials before the account could be used. 415 * 416 * @return whether or not the Account's credentials are expired. 417 */ 418 public boolean isCredentialsExpired() { 419 return credentialsExpired; 420 } 421 422 /** 423 * Sets whether or not the Account's credentials are expired. A <code>true</code> value indicates that the Subject 424 * or application administrator would need to change their credentials before the account could be used. 425 * 426 * @param credentialsExpired <code>true</code> if this Account's credentials are expired and need to be changed, 427 * <code>false</code> otherwise. 428 */ 429 public void setCredentialsExpired(boolean credentialsExpired) { 430 this.credentialsExpired = credentialsExpired; 431 } 432 433 434 /** 435 * Merges the specified <code>AuthenticationInfo</code> into this <code>Account</code>. 436 * <p/> 437 * If the specified argument is also an instance of {@link SimpleAccount SimpleAccount}, the 438 * {@link #isLocked()} and {@link #isCredentialsExpired()} attributes are merged (set on this instance) as well 439 * (only if their values are <code>true</code>). 440 * 441 * @param info the <code>AuthenticationInfo</code> to merge into this account. 442 */ 443 public void merge(AuthenticationInfo info) { 444 authcInfo.merge(info); 445 446 // Merge SimpleAccount specific info 447 if (info instanceof SimpleAccount) { 448 SimpleAccount otherAccount = (SimpleAccount) info; 449 if (otherAccount.isLocked()) { 450 setLocked(true); 451 } 452 453 if (otherAccount.isCredentialsExpired()) { 454 setCredentialsExpired(true); 455 } 456 } 457 } 458 459 /** 460 * If the {@link #getPrincipals() principals} are not null, returns <code>principals.hashCode()</code>, otherwise 461 * returns 0 (zero). 462 * 463 * @return <code>principals.hashCode()</code> if they are not null, 0 (zero) otherwise. 464 */ 465 public int hashCode() { 466 return (getPrincipals() != null ? getPrincipals().hashCode() : 0); 467 } 468 469 /** 470 * Returns <code>true</code> if the specified object is also a {@link SimpleAccount SimpleAccount} and its 471 * {@link #getPrincipals() principals} are equal to this object's <code>principals</code>, <code>false</code> otherwise. 472 * 473 * @param o the object to test for equality. 474 * @return <code>true</code> if the specified object is also a {@link SimpleAccount SimpleAccount} and its 475 * {@link #getPrincipals() principals} are equal to this object's <code>principals</code>, <code>false</code> otherwise. 476 */ 477 public boolean equals(Object o) { 478 if (o == this) { 479 return true; 480 } 481 if (o instanceof SimpleAccount) { 482 SimpleAccount sa = (SimpleAccount) o; 483 //principal should be unique across the application, so only check this for equality: 484 return (getPrincipals() != null ? getPrincipals().equals(sa.getPrincipals()) : sa.getPrincipals() == null); 485 } 486 return false; 487 } 488 489 /** 490 * Returns {@link #getPrincipals() principals}.toString() if they are not null, otherwise prints out the string 491 * "empty" 492 * 493 * @return the String representation of this Account object. 494 */ 495 public String toString() { 496 return getPrincipals() != null ? getPrincipals().toString() : "empty"; 497 } 498 499}