mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 09:12:14 +00:00
Add account expiration and credentials expiration capabilities.
This commit is contained in:
parent
db51400570
commit
c939bcb176
@ -0,0 +1,49 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account has
|
||||
* expired. Makes no assertion as to whether or not the credentials were
|
||||
* valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccountExpiredException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
/**
|
||||
* Constructs a <code>AccountExpiredException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public AccountExpiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>AccountExpiredException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public AccountExpiredException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity;
|
||||
|
||||
/**
|
||||
* Thrown if an authentication request is rejected because the account's
|
||||
* credentials have expired. Makes no assertion as to whether or not the
|
||||
* credentials were valid.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CredentialsExpiredException extends AuthenticationException {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
/**
|
||||
* Constructs a <code>CredentialsExpiredException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public CredentialsExpiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>CredentialsExpiredException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public CredentialsExpiredException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
@ -15,16 +15,20 @@
|
||||
|
||||
package net.sf.acegisecurity.providers.dao;
|
||||
|
||||
import net.sf.acegisecurity.AccountExpiredException;
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.CredentialsExpiredException;
|
||||
import net.sf.acegisecurity.DisabledException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
import net.sf.acegisecurity.providers.AuthenticationProvider;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountExpiredEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureCredentialsExpiredEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailurePasswordEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureUsernameNotFoundEvent;
|
||||
@ -228,7 +232,7 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
|
||||
authentication,
|
||||
new User("".equals(username)
|
||||
? "EMPTY_STRING_PROVIDED" : username, "*****",
|
||||
false, new GrantedAuthority[0])));
|
||||
false, false, false, new GrantedAuthority[0])));
|
||||
}
|
||||
|
||||
throw ex;
|
||||
@ -244,6 +248,25 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
|
||||
throw new DisabledException("User is disabled");
|
||||
}
|
||||
|
||||
if (!user.isAccountNonExpired()) {
|
||||
if (this.context != null) {
|
||||
context.publishEvent(new AuthenticationFailureAccountExpiredEvent(
|
||||
authentication, user));
|
||||
}
|
||||
|
||||
throw new AccountExpiredException("User account has expired");
|
||||
}
|
||||
|
||||
if (!user.isCredentialsNonExpired()) {
|
||||
if (this.context != null) {
|
||||
context.publishEvent(new AuthenticationFailureCredentialsExpiredEvent(
|
||||
authentication, user));
|
||||
}
|
||||
|
||||
throw new CredentialsExpiredException(
|
||||
"User credentials have expired");
|
||||
}
|
||||
|
||||
if (!isPasswordCorrect(authentication, user)) {
|
||||
// Password incorrect, so ensure we're using most current password
|
||||
if (cacheWasUsed) {
|
||||
|
@ -15,16 +15,20 @@
|
||||
|
||||
package net.sf.acegisecurity.providers.dao;
|
||||
|
||||
import net.sf.acegisecurity.AccountExpiredException;
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationException;
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.CredentialsExpiredException;
|
||||
import net.sf.acegisecurity.DisabledException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
import net.sf.acegisecurity.providers.AuthenticationProvider;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountExpiredEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureCredentialsExpiredEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureUsernameOrPasswordEvent;
|
||||
import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent;
|
||||
@ -179,7 +183,7 @@ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider
|
||||
|
||||
context.publishEvent(new AuthenticationFailureUsernameOrPasswordEvent(
|
||||
authentication,
|
||||
new User(username, "*****", false,
|
||||
new User(username, "*****", false, false, false,
|
||||
new GrantedAuthority[0])));
|
||||
}
|
||||
|
||||
@ -196,6 +200,25 @@ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider
|
||||
throw new DisabledException("User is disabled");
|
||||
}
|
||||
|
||||
if (!user.isAccountNonExpired()) {
|
||||
if (this.context != null) {
|
||||
context.publishEvent(new AuthenticationFailureAccountExpiredEvent(
|
||||
authentication, user));
|
||||
}
|
||||
|
||||
throw new AccountExpiredException("User account has expired");
|
||||
}
|
||||
|
||||
if (!user.isCredentialsNonExpired()) {
|
||||
if (this.context != null) {
|
||||
context.publishEvent(new AuthenticationFailureCredentialsExpiredEvent(
|
||||
authentication, user));
|
||||
}
|
||||
|
||||
throw new CredentialsExpiredException(
|
||||
"User credentials have expired");
|
||||
}
|
||||
|
||||
if (!cacheWasUsed) {
|
||||
// Put into cache
|
||||
this.userCache.putUserInCache(user);
|
||||
|
@ -0,0 +1,37 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.providers.dao.event;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* account having expired.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureAccountExpiredEvent
|
||||
extends AuthenticationEvent {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public AuthenticationFailureAccountExpiredEvent(
|
||||
Authentication authentication, UserDetails user) {
|
||||
super(authentication, user);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.providers.dao.event;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
|
||||
|
||||
/**
|
||||
* Application event which indicates authentication failure due to the user's
|
||||
* credentials having expired.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuthenticationFailureCredentialsExpiredEvent
|
||||
extends AuthenticationEvent {
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public AuthenticationFailureCredentialsExpiredEvent(
|
||||
Authentication authentication, UserDetails user) {
|
||||
super(authentication, user);
|
||||
}
|
||||
}
|
@ -37,6 +37,8 @@ public class User implements UserDetails {
|
||||
private String password;
|
||||
private String username;
|
||||
private GrantedAuthority[] authorities;
|
||||
private boolean accountNonExpired;
|
||||
private boolean credentialsNonExpired;
|
||||
private boolean enabled;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
@ -57,8 +59,38 @@ public class User implements UserDetails {
|
||||
* @throws IllegalArgumentException if a <code>null</code> value was passed
|
||||
* either as a parameter or as an element in the
|
||||
* <code>GrantedAuthority[]</code> array
|
||||
*
|
||||
* @deprecated use new constructor with extended properties (this
|
||||
* constructor will be removed from release 1.0.0)
|
||||
*/
|
||||
public User(String username, String password, boolean enabled,
|
||||
GrantedAuthority[] authorities) throws IllegalArgumentException {
|
||||
this(username, password, enabled, true, true, authorities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the <code>User</code> with the details required by {@link
|
||||
* DaoAuthenticationProvider}.
|
||||
*
|
||||
* @param username the username presented to the
|
||||
* <code>DaoAuthenticationProvider</code>
|
||||
* @param password the password that should be presented to the
|
||||
* <code>DaoAuthenticationProvider</code>
|
||||
* @param enabled set to <code>true</code> if the user is enabled
|
||||
* @param accountNonExpired set to <code>true</code> if the account has not
|
||||
* expired
|
||||
* @param credentialsNonExpired set to <code>true</code> if the credentials
|
||||
* have not expired
|
||||
* @param authorities the authorities that should be granted to the caller
|
||||
* if they presented the correct username and password and the user
|
||||
* is enabled
|
||||
*
|
||||
* @throws IllegalArgumentException if a <code>null</code> value was passed
|
||||
* either as a parameter or as an element in the
|
||||
* <code>GrantedAuthority[]</code> array
|
||||
*/
|
||||
public User(String username, String password, boolean enabled,
|
||||
boolean accountNonExpired, boolean credentialsNonExpired,
|
||||
GrantedAuthority[] authorities) throws IllegalArgumentException {
|
||||
if (((username == null) || "".equals(username)) || (password == null)
|
||||
|| "".equals(password) || (authorities == null)) {
|
||||
@ -78,6 +110,8 @@ public class User implements UserDetails {
|
||||
this.password = password;
|
||||
this.enabled = enabled;
|
||||
this.authorities = authorities;
|
||||
this.accountNonExpired = accountNonExpired;
|
||||
this.credentialsNonExpired = credentialsNonExpired;
|
||||
}
|
||||
|
||||
protected User() {
|
||||
@ -86,10 +120,18 @@ public class User implements UserDetails {
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public boolean isAccountNonExpired() {
|
||||
return accountNonExpired;
|
||||
}
|
||||
|
||||
public GrantedAuthority[] getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return credentialsNonExpired;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
@ -43,6 +43,16 @@ import java.io.Serializable;
|
||||
public interface UserDetails extends Serializable {
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* Indicates whether the user's account has expired. An expired account
|
||||
* cannot be authenticated.
|
||||
*
|
||||
* @return <code>true</code> if the user's account is valid (ie
|
||||
* non-expired), <code>false</code> if no longer valid (ie
|
||||
* expired)
|
||||
*/
|
||||
public boolean isAccountNonExpired();
|
||||
|
||||
/**
|
||||
* Returns the authorities granted to the user. Cannot return
|
||||
* <code>null</code>.
|
||||
@ -51,6 +61,16 @@ public interface UserDetails extends Serializable {
|
||||
*/
|
||||
public GrantedAuthority[] getAuthorities();
|
||||
|
||||
/**
|
||||
* Indicates whether the user's credentials (password) has expired. Expired
|
||||
* credentials prevent authentication.
|
||||
*
|
||||
* @return <code>true</code> if the user's credentials are valid (ie
|
||||
* non-expired), <code>false</code> if no longer valid (ie
|
||||
* expired)
|
||||
*/
|
||||
public boolean isCredentialsNonExpired();
|
||||
|
||||
/**
|
||||
* Indicates whether the user is enabled or disabled. A disabled user
|
||||
* cannot be authenticated.
|
||||
|
@ -58,6 +58,13 @@ import javax.sql.DataSource;
|
||||
* the {@link MappingSqlQuery} instances used, via the {@link
|
||||
* #initMappingSqlQueries()} extension point.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* In order to minimise backward compatibility issues, this DAO does not
|
||||
* recognise the expiration of user accounts or the expiration of user
|
||||
* credentials. However, it does recognise and honour the user
|
||||
* enabled/disabled column.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author colin sampaleanu
|
||||
@ -185,14 +192,14 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements AuthenticationDao {
|
||||
arrayAuths = (GrantedAuthority[]) dbAuths.toArray(arrayAuths);
|
||||
|
||||
return new User(user.getUsername(), user.getPassword(),
|
||||
user.isEnabled(), arrayAuths);
|
||||
user.isEnabled(), true, true, arrayAuths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to add their own granted authorities to the list to be
|
||||
* returned in the <code>User</code>.
|
||||
*
|
||||
* @param username the username, for use by finder methods
|
||||
* @param username the username, for use by finder methods
|
||||
* @param authorities the current granted authorities, as populated from
|
||||
* the <code>authoritiesByUsername</code> mapping
|
||||
*/
|
||||
@ -248,7 +255,8 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements AuthenticationDao {
|
||||
String username = rs.getString(1);
|
||||
String password = rs.getString(2);
|
||||
boolean enabled = rs.getBoolean(3);
|
||||
UserDetails user = new User(username, password, enabled,
|
||||
UserDetails user = new User(username, password, enabled, true,
|
||||
true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
|
||||
|
||||
return user;
|
||||
|
@ -56,6 +56,12 @@ import java.util.Properties;
|
||||
* If the above requirements are not met, the invalid entry will be silently
|
||||
* ignored.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This editor always assumes each entry has a non-expired account and
|
||||
* non-expired credentials. However, it does honour the user enabled/disabled
|
||||
* flag as described above.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
@ -91,7 +97,7 @@ public class UserMapEditor extends PropertyEditorSupport {
|
||||
// Make a user object, assuming the properties were properly provided
|
||||
if (attr != null) {
|
||||
UserDetails user = new User(username, attr.getPassword(),
|
||||
attr.isEnabled(), attr.getAuthorities());
|
||||
attr.isEnabled(), true, true, attr.getAuthorities());
|
||||
userMap.addUser(user);
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase {
|
||||
.getPrincipal(), new NamedEntityObjectIdentity("OBJECT", "100"),
|
||||
null, 2);
|
||||
private UsernamePasswordAuthenticationToken scottWithUserDetails = new UsernamePasswordAuthenticationToken(new User(
|
||||
"scott", "NOT_USED", true,
|
||||
"scott", "NOT_USED", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl(
|
||||
"ROLE_EVERYBODY")}), "not used",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_TWO")});
|
||||
|
@ -327,7 +327,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
||||
}
|
||||
|
||||
private UserDetails makeUserDetails() {
|
||||
return new User("user", "password", true,
|
||||
return new User("user", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
}
|
||||
@ -337,7 +337,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
||||
private class MockAuthoritiesPopulator implements CasAuthoritiesPopulator {
|
||||
public UserDetails getUserDetails(String casUserId)
|
||||
throws AuthenticationException {
|
||||
return new User("user", "password", true,
|
||||
return new User("user", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl(
|
||||
"ROLE_B")});
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ public class CasAuthenticationTokenTests extends TestCase {
|
||||
}
|
||||
|
||||
private UserDetails makeUserDetails() {
|
||||
return new User("user", "password", true,
|
||||
return new User("user", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class EhCacheBasedTicketCacheTests extends TestCase {
|
||||
List proxyList = new Vector();
|
||||
proxyList.add("https://localhost/newPortal/j_acegi_cas_security_check");
|
||||
|
||||
User user = new User("marissa", "password", true,
|
||||
User user = new User("marissa", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
|
||||
|
@ -139,7 +139,7 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase {
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", "koala", true,
|
||||
return new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
|
@ -17,9 +17,11 @@ package net.sf.acegisecurity.providers.dao;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.AccountExpiredException;
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.CredentialsExpiredException;
|
||||
import net.sf.acegisecurity.DisabledException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
@ -73,6 +75,38 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfAccountExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
|
||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AccountExpiredException");
|
||||
} catch (AccountExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfCredentialsExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
|
||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown CredentialsExpiredException");
|
||||
} catch (CredentialsExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfUserDisabled() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
@ -426,7 +460,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", password, true,
|
||||
return new User("marissa", password, true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
@ -442,6 +476,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", "koala{SYSTEM_SALT_VALUE}", true,
|
||||
true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
@ -455,7 +490,37 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", false,
|
||||
return new User("peter", "opal", false, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: "
|
||||
+ username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockAuthenticationDaoUserPeterAccountExpired
|
||||
implements AuthenticationDao {
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, false, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: "
|
||||
+ username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockAuthenticationDaoUserPeterCredentialsExpired
|
||||
implements AuthenticationDao {
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, true, false,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
|
@ -17,9 +17,11 @@ package net.sf.acegisecurity.providers.dao;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.AccountExpiredException;
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationServiceException;
|
||||
import net.sf.acegisecurity.BadCredentialsException;
|
||||
import net.sf.acegisecurity.CredentialsExpiredException;
|
||||
import net.sf.acegisecurity.DisabledException;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
@ -68,6 +70,38 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfAccountExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
|
||||
PasswordDaoAuthenticationProvider provider = new PasswordDaoAuthenticationProvider();
|
||||
provider.setPasswordAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AccountExpiredException");
|
||||
} catch (AccountExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfCredentialsExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
|
||||
PasswordDaoAuthenticationProvider provider = new PasswordDaoAuthenticationProvider();
|
||||
provider.setPasswordAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown CredentialsExpiredException");
|
||||
} catch (CredentialsExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfUserDisabled() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
|
||||
"opal");
|
||||
@ -290,7 +324,7 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
|
||||
String password)
|
||||
throws BadCredentialsException, DataAccessException {
|
||||
if ("marissa".equals(username) && "koala".equals(password)) {
|
||||
return new User("marissa", "koala", true,
|
||||
return new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
@ -305,7 +339,7 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
|
||||
String password)
|
||||
throws BadCredentialsException, DataAccessException {
|
||||
if ("peter".equals(username) && "opal".equals(password)) {
|
||||
return new User("peter", "opal", false,
|
||||
return new User("peter", "opal", false, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
@ -314,6 +348,38 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private class MockAuthenticationDaoUserPeterAccountExpired
|
||||
implements PasswordAuthenticationDao {
|
||||
public UserDetails loadUserByUsernameAndPassword(String username,
|
||||
String password)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, false, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: "
|
||||
+ username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockAuthenticationDaoUserPeterCredentialsExpired
|
||||
implements PasswordAuthenticationDao {
|
||||
public UserDetails loadUserByUsernameAndPassword(String username,
|
||||
String password)
|
||||
throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, true, false,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: "
|
||||
+ username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserCache implements UserCache {
|
||||
private Map cache = new HashMap();
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class UserTests extends TestCase {
|
||||
|
||||
public void testNullValuesRejected() throws Exception {
|
||||
try {
|
||||
UserDetails user = new User(null, "koala", true,
|
||||
UserDetails user = new User(null, "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
@ -69,7 +69,7 @@ public class UserTests extends TestCase {
|
||||
}
|
||||
|
||||
try {
|
||||
UserDetails user = new User("marissa", null, true,
|
||||
UserDetails user = new User("marissa", null, true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
@ -78,14 +78,15 @@ public class UserTests extends TestCase {
|
||||
}
|
||||
|
||||
try {
|
||||
UserDetails user = new User("marissa", "koala", true, null);
|
||||
UserDetails user = new User("marissa", "koala", true, true, true,
|
||||
null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
UserDetails user = new User("marissa", "koala", true,
|
||||
UserDetails user = new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null});
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
@ -96,7 +97,7 @@ public class UserTests extends TestCase {
|
||||
public void testNullWithinGrantedAuthorityElementIsRejected()
|
||||
throws Exception {
|
||||
try {
|
||||
UserDetails user = new User(null, "koala", true,
|
||||
UserDetails user = new User(null, "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO"), null, new GrantedAuthorityImpl(
|
||||
"ROLE_THREE")});
|
||||
@ -107,7 +108,7 @@ public class UserTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testUserGettersSetter() throws Exception {
|
||||
UserDetails user = new User("marissa", "koala", true,
|
||||
UserDetails user = new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
assertEquals("marissa", user.getUsername());
|
||||
@ -120,7 +121,7 @@ public class UserTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testUserIsEnabled() throws Exception {
|
||||
UserDetails user = new User("marissa", "koala", false,
|
||||
UserDetails user = new User("marissa", "koala", false, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
assertTrue(!user.isEnabled());
|
||||
|
@ -95,7 +95,7 @@ public class EhCacheBasedUserCacheTests extends TestCase {
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
return new User("john", "password", true,
|
||||
return new User("john", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class NullUserCacheTests extends TestCase {
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
return new User("john", "password", true,
|
||||
return new User("john", "password", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public class AuthenticationEventTests extends TestCase {
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
User user = new User("foo", "bar", true,
|
||||
User user = new User("foo", "bar", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOOBAR")});
|
||||
|
||||
return user;
|
||||
|
@ -90,7 +90,7 @@ public class LoggerListenerTests extends TestCase {
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
User user = new User("foo", "bar", true,
|
||||
User user = new User("foo", "bar", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOOBAR")});
|
||||
|
||||
return user;
|
||||
|
@ -52,13 +52,13 @@ public class UserMapTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testAddAndRetrieveUser() {
|
||||
UserDetails marissa = new User("marissa", "koala", true,
|
||||
UserDetails marissa = new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
UserDetails scott = new User("scott", "wombat", true,
|
||||
UserDetails scott = new User("scott", "wombat", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_THREE")});
|
||||
UserDetails peter = new User("peter", "opal", true,
|
||||
UserDetails peter = new User("peter", "opal", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_FOUR")});
|
||||
UserMap map = new UserMap();
|
||||
@ -85,7 +85,7 @@ public class UserMapTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testUnknownUserIsNotRetrieved() {
|
||||
UserDetails marissa = new User("marissa", "koala", true,
|
||||
UserDetails marissa = new User("marissa", "koala", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
|
||||
"ROLE_TWO")});
|
||||
UserMap map = new UserMap();
|
||||
|
@ -67,7 +67,7 @@ public class ReflectionSaltSourceTests extends TestCase {
|
||||
ReflectionSaltSource saltSource = new ReflectionSaltSource();
|
||||
saltSource.setUserPropertyToUse("getDoesNotExist");
|
||||
|
||||
UserDetails user = new User("scott", "wombat", true,
|
||||
UserDetails user = new User("scott", "wombat", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
|
||||
|
||||
try {
|
||||
@ -89,7 +89,7 @@ public class ReflectionSaltSourceTests extends TestCase {
|
||||
saltSource.setUserPropertyToUse("getUsername");
|
||||
saltSource.afterPropertiesSet();
|
||||
|
||||
UserDetails user = new User("scott", "wombat", true,
|
||||
UserDetails user = new User("scott", "wombat", true, true, true,
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
|
||||
assertEquals("scott", saltSource.getSalt(user));
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class AuthenticationTagTests extends TestCase {
|
||||
public void testOperationWhenPrincipalIsAUserDetailsInstance()
|
||||
throws JspException {
|
||||
Authentication auth = new TestingAuthenticationToken(new User(
|
||||
"marissaUserDetails", "koala", true,
|
||||
"marissaUserDetails", "koala", true, true, true,
|
||||
new GrantedAuthority[] {}), "koala",
|
||||
new GrantedAuthority[] {});
|
||||
SecureContext sc = new SecureContextImpl();
|
||||
|
@ -78,7 +78,7 @@ public class ContextHolderAwareRequestWrapperTests extends TestCase {
|
||||
throws Exception {
|
||||
SecureContext sc = new SecureContextImpl();
|
||||
Authentication auth = new TestingAuthenticationToken(new User(
|
||||
"marissaAsUserDetails", "koala", true,
|
||||
"marissaAsUserDetails", "koala", true, true, true,
|
||||
new GrantedAuthority[] {}), "koala",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl(
|
||||
"ROLE_FOOBAR")});
|
||||
|
@ -1042,7 +1042,11 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
|
||||
authentication is denied. An
|
||||
<literal>AuthenticationServiceException</literal> is also provided,
|
||||
which indicates the authentication system could not process the
|
||||
request (eg a database was unavailable).</para>
|
||||
request (eg a database was unavailable).
|
||||
<literal>AuthenticationException</literal> also has a
|
||||
<literal>CredentialsExpiredException</literal> and
|
||||
<literal>AccoungtExpiredException</literal> subclass, although these
|
||||
are less commonly used.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="security-authentication-provider">
|
||||
@ -1295,6 +1299,23 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
|
||||
normally the case when an account is locked.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AuthenticationFailureAccountExpiredEvent</literal>
|
||||
is published when an authentication request is unsuccessful
|
||||
because the returned <literal>UserDetails</literal> indicates the
|
||||
account has expired. Some applications may wish to distinguish
|
||||
between an account being disabled and expired.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AuthenticationFailureCredentialsExpiredEvent</literal>
|
||||
is published when an authentication request is unsuccessful
|
||||
because the returned <literal>UserDetails</literal> indicates the
|
||||
account's credentials have expired. Some applications may wish to
|
||||
expire the credentials if, for example, a password is not changed
|
||||
with sufficient regularity.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
|
||||
is published when an authentication request is unsuccessful
|
||||
@ -3184,8 +3205,8 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
||||
<para>As the <literal>Authentication</literal> object is now in
|
||||
the well-known location, it is handled like any other
|
||||
authentication approach. Usually the
|
||||
<literal>AutoIntegrationFilter</literal> will be used to associate
|
||||
the <literal>Authentication</literal> object with the
|
||||
<literal>HttpSessionIntegrationFilter</literal> will be used to
|
||||
associate the <literal>Authentication</literal> object with the
|
||||
<literal>ContextHolder</literal> for the duration of each
|
||||
request.</para>
|
||||
</listitem>
|
||||
@ -4169,8 +4190,8 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Acegi Security System for Spring Auto Integration Filter
|
||||
(<literal>AutoIntegrationFilter</literal>)</para>
|
||||
<para>Acegi Security System for Spring HTTP Session Integration
|
||||
Filter (<literal>HttpSessionIntegrationFilter</literal>)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
@ -45,6 +45,8 @@
|
||||
<action dev="benalex" type="add">Added AbstractProcessingFilter property to always use defaultTargetUrl</action>
|
||||
<action dev="benalex" type="add">Added ContextHolderAwareRequestWrapper to integrate with getRemoteUser()</action>
|
||||
<action dev="benalex" type="add">Added attempted username to view if processed by AuthenticationProcessingFilter</action>
|
||||
<action dev="benalex" type="add">Added UserDetails account and credentials expiration methods</action>
|
||||
<action dev="benalex" type="add">Added exceptions and events to support new UserDetails methods</action>
|
||||
<action dev="benalex" type="update">Improved BasicAclProvider to only respond to specified ACL object requests</action>
|
||||
<action dev="benalex" type="update">Refactored MethodDefinitionSource to work with Method, not MethodInvocation</action>
|
||||
<action dev="benalex" type="update">Refactored AbstractFilterInvocationDefinitionSource to work with URL Strings alone</action>
|
||||
@ -55,6 +57,7 @@
|
||||
<action dev="benalex" type="update">Refactored EH-CACHE implementations to use Spring IoC defined caches instead</action>
|
||||
<action dev="benalex" type="update">AbstractProcessingFilter now has various hook methods to assist subclasses</action>
|
||||
<action dev="benalex" type="update">DaoAuthenticationProvider better detects AuthenticationDao interface violations</action>
|
||||
<action dev="benalex" type="update">The User class has a new constructor (the old constructor is deprecated)</action>
|
||||
<action dev="benalex" type="fix">Fixed ambiguous column references in JdbcDaoImpl default query</action>
|
||||
<action dev="benalex" type="fix">Fixed AbstractProcessingFilter to use removeAttribute (JRun compatibility)</action>
|
||||
<action dev="benalex" type="fix">Fixed GrantedAuthorityEffectiveAclResolver support of UserDetails principals</action>
|
||||
|
@ -9,8 +9,15 @@
|
||||
The following should help most casual users of the project update their
|
||||
applications:
|
||||
<ul>
|
||||
<li>UserDetails now has two extra methods. Most people who have extended
|
||||
Acegi Security's default User implementation of UserDetails will be fine, as
|
||||
the constructor sets sensible defaults for the extra methods. People who
|
||||
have written their own UserDetails implementation from scratch will need to
|
||||
add the additional two methods. Returning true to both methods will normally
|
||||
be correct.
|
||||
</li>
|
||||
<li>MethodDefinitionMap, which is usually used by MethodSecurityInterceptor
|
||||
for its objectDefinitionSource property, has been changed. From 0.7, when
|
||||
for its objectDefinitionSource property, has been changed. From 0.7.0, when
|
||||
MethodDefinitionMap is queried for configuration attributes associated with
|
||||
secure MethodInvocations, it will use any method matching in the method
|
||||
invocation class (as it always has) plus any method matching any interface
|
||||
|
@ -164,7 +164,7 @@ public class LdapPasswordAuthenticationDao implements PasswordAuthenticationDao
|
||||
|
||||
String[] ldapRoles = (String[]) roles.toArray(new String[] {});
|
||||
|
||||
return new User(username, password, true,
|
||||
return new User(username, password, true, true, true,
|
||||
getGrantedAuthorities(ldapRoles));
|
||||
} catch (AuthenticationException ex) {
|
||||
throw new BadCredentialsException(BAD_CREDENTIALS_EXCEPTION_MESSAGE,
|
||||
|
Loading…
x
Reference in New Issue
Block a user