From 5d9d73473565c46e4df9654478f9015f293aaede Mon Sep 17 00:00:00 2001 From: Colin Sampaleanu Date: Thu, 15 Apr 2004 16:32:09 +0000 Subject: [PATCH] more final version of the various PasswordEncoder implementations. add unit tests for PasswordEncoder implementations. remove ignore password case and ignore username case flags and handling from DaoAuthenticationProvider. remove requirement described in JavaDoc for AuthenticationDao that it ignore case when returning a user by username. Implementations may still do so if configured as such. --- .../dao/BaseDigestPasswordEncoder.java | 44 ++++++++++++++ .../dao/DaoAuthenticationProvider.java | 44 +------------- .../providers/dao/MD5PasswordEncoder.java | 46 ++++++++------- .../providers/dao/PasswordEncoder.java | 4 +- .../dao/PlaintextPasswordEncoder.java | 25 +++++++- .../providers/dao/SHAPasswordEncoder.java | 30 ++++++---- .../userdetails/UserDetailsService.java | 8 ++- .../acegisecurity/adapters/acegisecurity.xml | 2 - .../providers/dao/jdbc/acegisecurity-jdbc.xml | 2 - .../adapters/adaptertest-valid.xml | 2 - .../web/securityfiltertest-valid.xml | 2 - .../dao/DaoAuthenticationProviderTests.java | 43 +------------- .../providers/dao/MD5PasswordEncoderTest.java | 47 +++++++++++++++ .../dao/PlaintextPasswordEncoderTest.java | 59 +++++++++++++++++++ .../providers/dao/SHAPasswordEncoderTest.java | 47 +++++++++++++++ .../ui/webapp/filtertest-valid.xml | 2 - docs/reference/src/index.xml | 7 --- .../contacts/etc/ca/applicationContext.xml | 2 - .../contacts/etc/ca/resin-acegisecurity.xml | 2 - .../etc/filter/applicationContext.xml | 2 - .../etc/filter/web-filters-acegisecurity.xml | 2 - test/acegisecuritytest.properties | 2 +- 22 files changed, 274 insertions(+), 150 deletions(-) create mode 100644 core/src/main/java/org/acegisecurity/providers/dao/BaseDigestPasswordEncoder.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java diff --git a/core/src/main/java/org/acegisecurity/providers/dao/BaseDigestPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/dao/BaseDigestPasswordEncoder.java new file mode 100644 index 0000000000..0c49fce06a --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/BaseDigestPasswordEncoder.java @@ -0,0 +1,44 @@ +/* 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; + +/** + *

+ * Convenience base for Digest password encoders + *

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public abstract class BaseDigestPasswordEncoder implements PasswordEncoder { + + //~ Instance fields ======================================================== + private boolean encodeHashAsBase64 = false; + + //~ Methods ================================================================ + + /** + * The encoded password is normally returned as Hex (32 char) version of the + * hash bytes. Setting this property to true will cause the encoded pass to + * be returned as Base64 text, which will consume 24 characters. + */ + public void setEncodeHashAsBase64(boolean encodeHashAsBase64) { + this.encodeHashAsBase64 = encodeHashAsBase64; + } + public boolean getEncodeHashAsBase64() { + return encodeHashAsBase64; + } + +} diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java index 0f06d285f3..3f428834b6 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -47,8 +47,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, private AuthenticationDao authenticationDao; private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); - private boolean ignorePasswordCase = false; - private boolean ignoreUsernameCase = true; //~ Methods ================================================================ @@ -60,36 +58,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, return authenticationDao; } - /** - * Indicates whether the password comparison is case sensitive. Defaults to - * false, meaning an exact case match is required. - * - * @param ignorePasswordCase set to true for less stringent - * comparison - */ - public void setIgnorePasswordCase(boolean ignorePasswordCase) { - this.ignorePasswordCase = ignorePasswordCase; - } - - public boolean isIgnorePasswordCase() { - return ignorePasswordCase; - } - - /** - * Indicates whether the username search is case sensitive. Default to - * true, meaning an exact case match is not required. - * - * @param ignoreUsernameCase set to false for more stringent - * comparison - */ - public void setIgnoreUsernameCase(boolean ignoreUsernameCase) { - this.ignoreUsernameCase = ignoreUsernameCase; - } - - public boolean isIgnoreUsernameCase() { - return ignoreUsernameCase; - } - /** * Sets the PasswordEncoder instance to be used to encode and validate * passwords. If not set, {@link PlaintextPasswordEncoder} will be used by @@ -123,20 +91,12 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, throw new BadCredentialsException("Bad credentials presented"); } catch (DataAccessException repositoryProblem) { throw new AuthenticationServiceException(repositoryProblem - .getMessage()); - } - - if ((!this.ignoreUsernameCase) - && (!user.getUsername().equals(authentication.getPrincipal() - .toString()))) { - throw new BadCredentialsException("Bad credentials presented"); + .getMessage(), repositoryProblem); } if (!passwordEncoder.isPasswordValid(user.getPassword(), - authentication.getCredentials().toString(), user, - ignorePasswordCase)) { + authentication.getCredentials().toString(), user)) throw new BadCredentialsException("Bad credentials presented"); - } if (!user.isEnabled()) { throw new DisabledException("User is disabled"); diff --git a/core/src/main/java/org/acegisecurity/providers/dao/MD5PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/dao/MD5PasswordEncoder.java index 4eb4745191..c3694bbe94 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/MD5PasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/MD5PasswordEncoder.java @@ -15,6 +15,7 @@ package net.sf.acegisecurity.providers.dao; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; @@ -24,34 +25,39 @@ import org.apache.commons.codec.digest.DigestUtils; *

* *

- * The ignorePasswordCase parameter is not used for this implementation. - *

- * - *

* A null password is encoded to the same value as an empty ("") password. *

* * @author colin sampaleanu * @version $Id$ */ -public class MD5PasswordEncoder implements PasswordEncoder { +public class MD5PasswordEncoder extends BaseDigestPasswordEncoder implements PasswordEncoder { //~ Methods ================================================================ - /* (non-Javadoc) - * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(net.sf.acegisecurity.providers.dao.User, java.lang.String, boolean) - */ - public boolean isPasswordValid(String encPass, String rawPass, - Object saltSource, boolean ignorePasswordCase) { - String pass1 = "" + encPass; - String pass2 = DigestUtils.md5Hex("" + rawPass); + /* (non-Javadoc) + * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(java.lang.String, java.lang.String, java.lang.Object) + */ + public boolean isPasswordValid(String encPass, String rawPass, Object saltSource) { - return pass1.equals(pass2); - } + String pass1 = "" + encPass; + String pass2 = encodeInternal("" + rawPass); - /* (non-Javadoc) - * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#encodePassword(java.lang.String, java.lang.Object) - */ - public String encodePassword(String rawPass, Object saltSource) { - return DigestUtils.md5Hex("" + rawPass); - } + return pass1.equals(pass2); + } + + /* (non-Javadoc) + * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#encodePassword(java.lang.String, java.lang.Object) + */ + public String encodePassword(String rawPass, Object saltSource) { + return encodeInternal("" + rawPass); + } + + private String encodeInternal(String input) { + + if (!getEncodeHashAsBase64()) + return DigestUtils.md5Hex(input); + + byte[] encoded = Base64.encodeBase64(DigestUtils.md5(input)); + return new String(encoded); + } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/dao/PasswordEncoder.java index c7a91340ad..ba0db95c00 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/PasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/PasswordEncoder.java @@ -31,8 +31,8 @@ public interface PasswordEncoder { //~ Methods ================================================================ public boolean isPasswordValid(String encPass, String rawPass, - Object saltSource, boolean ignorePasswordCase) + Object saltSource) throws DataAccessException; - public String encodePassword(String rawPass, Object saltSource); + public String encodePassword(String rawPass, Object saltSource) throws DataAccessException; } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoder.java index e289740732..91c15bf87f 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoder.java @@ -24,13 +24,32 @@ package net.sf.acegisecurity.providers.dao; * @version $Id$ */ public class PlaintextPasswordEncoder implements PasswordEncoder { + + //~ Instance fields ======================================================== + private boolean ignorePasswordCase = false; + //~ Methods ================================================================ + + /** + * Indicates whether the password comparison is case sensitive. Defaults to + * false, meaning an exact case match is required. + * + * @param ignorePasswordCase set to true for less stringent + * comparison + */ + public void setIgnorePasswordCase(boolean ignorePasswordCase) { + this.ignorePasswordCase = ignorePasswordCase; + } + + public boolean isIgnorePasswordCase() { + return ignorePasswordCase; + } /* (non-Javadoc) - * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(net.sf.acegisecurity.providers.dao.User, java.lang.String, boolean) + * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(java.lang.String, java.lang.String, java.lang.Object) */ - public boolean isPasswordValid(String encPass, String rawPass, - Object saltSource, boolean ignorePasswordCase) { + public boolean isPasswordValid(String encPass, String rawPass, Object saltSource) { + String pass1 = "" + encPass; String pass2 = "" + rawPass; diff --git a/core/src/main/java/org/acegisecurity/providers/dao/SHAPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/dao/SHAPasswordEncoder.java index 19695ee9eb..2fd7ad523e 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/SHAPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/SHAPasswordEncoder.java @@ -15,35 +15,30 @@ package net.sf.acegisecurity.providers.dao; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; - /** *

* SHA implementation of PasswordEncoder. *

* *

- * The ignorePasswordCase parameter is not used for this implementation. - *

- * - *

* A null password is encoded to the same value as an empty ("") password. *

* * @author colin sampaleanu * @version $Id$ */ -public class SHAPasswordEncoder implements PasswordEncoder { - //~ Methods ================================================================ - +public class SHAPasswordEncoder extends BaseDigestPasswordEncoder implements PasswordEncoder { + /* (non-Javadoc) - * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(net.sf.acegisecurity.providers.dao.User, java.lang.String, boolean) + * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#isPasswordValid(java.lang.String, java.lang.String, java.lang.Object) */ - public boolean isPasswordValid(String encPass, String rawPass, - Object saltSource, boolean ignorePasswordCase) { + public boolean isPasswordValid(String encPass, String rawPass, Object saltSource) { + String pass1 = "" + encPass; - String pass2 = DigestUtils.shaHex("" + rawPass); + String pass2 = encodeInternal("" + rawPass); return pass1.equals(pass2); } @@ -52,6 +47,15 @@ public class SHAPasswordEncoder implements PasswordEncoder { * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#encodePassword(java.lang.String, java.lang.Object) */ public String encodePassword(String rawPass, Object saltSource) { - return DigestUtils.shaHex("" + rawPass); + return encodeInternal("" + rawPass); + } + + private String encodeInternal(String input) { + + if (!getEncodeHashAsBase64()) + return DigestUtils.shaHex(input); + + byte[] encoded = Base64.encodeBase64(DigestUtils.sha(input)); + return new String(encoded); } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java index 0c7f9597f2..057128acf2 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java +++ b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java @@ -34,9 +34,11 @@ public interface AuthenticationDao { //~ Methods ================================================================ /** - * Locates the user based on the username. The search is case insensitive, - * meaning the implementation must return any matching object irrespective - * of the mixture of uppercase and lowercase characters in the username. + * Locates the user based on the username. In the actual implementation, + * the search may possibly be case insensitive, or case insensitive + * depending on how the implementaion instance is configured. In this case, + * the User object that comes back may have a username that is of a different + * case than what was actually requested.. * * @param username the username presented to the {@link * DaoAuthenticationProvider} diff --git a/core/src/main/resources/org/acegisecurity/adapters/acegisecurity.xml b/core/src/main/resources/org/acegisecurity/adapters/acegisecurity.xml index df0c6150ca..38a23ee9ca 100644 --- a/core/src/main/resources/org/acegisecurity/adapters/acegisecurity.xml +++ b/core/src/main/resources/org/acegisecurity/adapters/acegisecurity.xml @@ -36,8 +36,6 @@ - false - true diff --git a/core/src/main/resources/org/acegisecurity/providers/dao/jdbc/acegisecurity-jdbc.xml b/core/src/main/resources/org/acegisecurity/providers/dao/jdbc/acegisecurity-jdbc.xml index 378ed2d3d3..51b8ae4078 100644 --- a/core/src/main/resources/org/acegisecurity/providers/dao/jdbc/acegisecurity-jdbc.xml +++ b/core/src/main/resources/org/acegisecurity/providers/dao/jdbc/acegisecurity-jdbc.xml @@ -25,8 +25,6 @@ - false - true diff --git a/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml index df0c6150ca..38a23ee9ca 100644 --- a/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml +++ b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml @@ -36,8 +36,6 @@ - false - true diff --git a/core/src/test/java/org/acegisecurity/intercept/web/securityfiltertest-valid.xml b/core/src/test/java/org/acegisecurity/intercept/web/securityfiltertest-valid.xml index f80229492e..60d1403380 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/securityfiltertest-valid.xml +++ b/core/src/test/java/org/acegisecurity/intercept/web/securityfiltertest-valid.xml @@ -34,8 +34,6 @@ - false - true diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java index a722193e65..eeeac4afc7 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -37,15 +37,6 @@ import org.springframework.dao.DataRetrievalFailureException; * @version $Id$ */ public class DaoAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== - - public DaoAuthenticationProviderTests() { - super(); - } - - public DaoAuthenticationProviderTests(String arg0) { - super(arg0); - } //~ Methods ================================================================ @@ -63,7 +54,6 @@ public class DaoAuthenticationProviderTests extends TestCase { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - assertTrue(!provider.isIgnorePasswordCase()); // default try { provider.authenticate(token); @@ -139,9 +129,6 @@ public class DaoAuthenticationProviderTests extends TestCase { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - assertTrue(provider.isIgnoreUsernameCase()); // default - provider.setIgnoreUsernameCase(false); - assertTrue(!provider.isIgnoreUsernameCase()); // changed try { provider.authenticate(token); @@ -151,32 +138,6 @@ public class DaoAuthenticationProviderTests extends TestCase { } } - public void testAuthenticateSuccessfulWithMixedCaseIfDefaultChanged() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "KOAla"); - - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - assertTrue(!provider.isIgnorePasswordCase()); // default - provider.setIgnorePasswordCase(true); - assertTrue(provider.isIgnorePasswordCase()); // changed - - Authentication result = provider.authenticate(token); - assertEquals("marissa", result.getPrincipal().toString()); - } - - public void testAuthenticateSuccessfulWithMixedCaseUsername() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", - "koala"); - - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - assertTrue(provider.isIgnoreUsernameCase()); // default - - Authentication result = provider.authenticate(token); - assertEquals("marissa", result.getPrincipal().toString()); - } - public void testAuthenticates() { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); @@ -239,7 +200,7 @@ public class DaoAuthenticationProviderTests extends TestCase { private class MockAuthenticationDaoUserMarissa implements AuthenticationDao { public User loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - if ("marissa".equals(username.toLowerCase())) { + if ("marissa".equals(username)) { return new User("marissa", "koala", true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( "ROLE_TWO")}); @@ -253,7 +214,7 @@ public class DaoAuthenticationProviderTests extends TestCase { private class MockAuthenticationDaoUserPeter implements AuthenticationDao { public User loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - if ("peter".equals(username.toLowerCase())) { + if ("peter".equals(username)) { return new User("peter", "opal", false, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( "ROLE_TWO")}); diff --git a/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java b/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java new file mode 100644 index 0000000000..12a2dc33ff --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java @@ -0,0 +1,47 @@ +/* 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; + +import junit.framework.TestCase; + +/** + *

+ * TestCase for PlaintextPasswordEncoder. + *

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public class MD5PasswordEncoderTest extends TestCase { + + public void testBasicFunctionality() { + + MD5PasswordEncoder pe = new MD5PasswordEncoder(); + String raw = "abc123"; + String badRaw = "abc321"; + String encoded = pe.encodePassword(raw, null); // no SALT source + assertTrue(pe.isPasswordValid(encoded, raw, null)); + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + assertTrue(encoded.length() == 32); + + // now try Base64 + pe.setEncodeHashAsBase64(true); + encoded = pe.encodePassword(raw, null); // no SALT source + assertTrue(pe.isPasswordValid(encoded, raw, null)); + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + assertTrue(encoded.length() != 32); + } + +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java b/core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java new file mode 100644 index 0000000000..8646d4dda8 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java @@ -0,0 +1,59 @@ +/* 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; + +import junit.framework.TestCase; + +/** + *

+ * TestCase for PlaintextPasswordEncoder. + *

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public class PlaintextPasswordEncoderTest extends TestCase { + + public void testBasicFunctionality() { + PlaintextPasswordEncoder pe = new PlaintextPasswordEncoder(); + + String raw = "abc123"; + String rawDiffCase = "AbC123"; + String badRaw = "abc321"; + // should be able to validate even without encoding + String encoded = raw; + assertTrue(pe.isPasswordValid(encoded, raw, null)); // no SALT source + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + + // now make sure encoded version it gives us back is comparable as well + encoded = pe.encodePassword(raw, null); + assertTrue(pe.isPasswordValid(encoded, raw, null)); // no SALT source + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + + // make sure default is not to ignore password case + encoded = pe.encodePassword(rawDiffCase, null); + assertFalse(pe.isPasswordValid(encoded, raw, null)); + + // now check for ignore password case + pe = new PlaintextPasswordEncoder(); + pe.setIgnorePasswordCase(true); + + // should be able to validate even without encoding + encoded = pe.encodePassword(rawDiffCase, null); + assertTrue(pe.isPasswordValid(encoded, raw, null)); + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + } + +} \ No newline at end of file diff --git a/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java b/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java new file mode 100644 index 0000000000..67f1707dfa --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java @@ -0,0 +1,47 @@ +/* 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; + +import junit.framework.TestCase; + +/** + *

+ * TestCase for SHAPasswordEncoder. + *

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public class SHAPasswordEncoderTest extends TestCase { + + public void testBasicFunctionality() { + + SHAPasswordEncoder pe = new SHAPasswordEncoder(); + String raw = "abc123"; + String badRaw = "abc321"; + String encoded = pe.encodePassword(raw, null); // no SALT source + assertTrue(pe.isPasswordValid(encoded, raw, null)); + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + assertTrue(encoded.length() == 40); + + // now try Base64 + pe.setEncodeHashAsBase64(true); + encoded = pe.encodePassword(raw, null); // no SALT source + assertTrue(pe.isPasswordValid(encoded, raw, null)); + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); + assertTrue(encoded.length() != 40); + + } +} diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/filtertest-valid.xml b/core/src/test/java/org/acegisecurity/ui/webapp/filtertest-valid.xml index df0c6150ca..38a23ee9ca 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/filtertest-valid.xml +++ b/core/src/test/java/org/acegisecurity/ui/webapp/filtertest-valid.xml @@ -36,8 +36,6 @@ - false - true diff --git a/docs/reference/src/index.xml b/docs/reference/src/index.xml index a9d08fbbe1..3087af5f5f 100644 --- a/docs/reference/src/index.xml +++ b/docs/reference/src/index.xml @@ -850,15 +850,8 @@ <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property> - <property name="ignorePasswordCase"><value>false</value></property> - <property name="ignoreUsernameCase"><value>true</value></property> </bean> - By default the DaoAuthenticationProvider does - not require an exact match on usernames, but it does require an exact - match on passwords. This behavior can be configured with the optional - properties shown above. - For a class to be able to provide the DaoAuthenticationProvider with access to an authentication repository, it must implement the diff --git a/samples/contacts/etc/ca/applicationContext.xml b/samples/contacts/etc/ca/applicationContext.xml index ac9cc5f9d3..b0189b1762 100644 --- a/samples/contacts/etc/ca/applicationContext.xml +++ b/samples/contacts/etc/ca/applicationContext.xml @@ -48,8 +48,6 @@ - false - true diff --git a/samples/contacts/etc/ca/resin-acegisecurity.xml b/samples/contacts/etc/ca/resin-acegisecurity.xml index bd5b4795e1..38175dc397 100644 --- a/samples/contacts/etc/ca/resin-acegisecurity.xml +++ b/samples/contacts/etc/ca/resin-acegisecurity.xml @@ -33,8 +33,6 @@ - false - true diff --git a/samples/contacts/etc/filter/applicationContext.xml b/samples/contacts/etc/filter/applicationContext.xml index d846576b4f..75365c16b8 100644 --- a/samples/contacts/etc/filter/applicationContext.xml +++ b/samples/contacts/etc/filter/applicationContext.xml @@ -43,8 +43,6 @@ - false - true diff --git a/samples/contacts/etc/filter/web-filters-acegisecurity.xml b/samples/contacts/etc/filter/web-filters-acegisecurity.xml index d1ae7aedf1..7a6b8bc63f 100644 --- a/samples/contacts/etc/filter/web-filters-acegisecurity.xml +++ b/samples/contacts/etc/filter/web-filters-acegisecurity.xml @@ -40,8 +40,6 @@ - false - true diff --git a/test/acegisecuritytest.properties b/test/acegisecuritytest.properties index 1a667a021a..832a797a7f 100644 --- a/test/acegisecuritytest.properties +++ b/test/acegisecuritytest.properties @@ -1,5 +1,5 @@ #HSQL database -#Wed Apr 14 23:23:24 EDT 2004 +#Thu Apr 15 12:20:59 EDT 2004 sql.strict_fk=true readonly=false sql.strong_fk=true