From 3d089aaa67bf0e2ab6e071eb862f4b95aedf5b46 Mon Sep 17 00:00:00 2001 From: Colin Sampaleanu Date: Fri, 16 Apr 2004 03:44:04 +0000 Subject: [PATCH] move and rename password encoding classes. change saltSource arument to salt argument, which impl may or may not use. --- .../dao/DaoAuthenticationProvider.java | 4 +- .../encoding/BaseDigestPasswordEncoder.java | 50 +++++++++++ .../encoding/Md5PasswordEncoder.java | 64 ++++++++++++++ .../providers/encoding/PasswordEncoder.java | 87 +++++++++++++++++++ .../encoding/PlaintextPasswordEncoder.java | 68 +++++++++++++++ .../encoding/ShaPasswordEncoder.java | 64 ++++++++++++++ .../userdetails/UserDetailsService.java | 6 +- .../dao/DaoAuthenticationProviderTests.java | 1 - .../providers/dao/MD5PasswordEncoderTest.java | 37 ++++---- .../dao/PlaintextPasswordEncoderTest.java | 59 +++++++------ .../providers/dao/SHAPasswordEncoderTest.java | 41 +++++---- .../sample/contact/ClientApplication.java | 2 +- test/acegisecuritytest.properties | 2 +- 13 files changed, 415 insertions(+), 70 deletions(-) create mode 100644 core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java create mode 100644 core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java create mode 100644 core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java create mode 100644 core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java create mode 100644 core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java 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 3f428834b6..b4a1e910e0 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -22,6 +22,7 @@ import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.DisabledException; import net.sf.acegisecurity.providers.AuthenticationProvider; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.providers.encoding.*; import org.springframework.beans.factory.InitializingBean; @@ -95,8 +96,9 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, } if (!passwordEncoder.isPasswordValid(user.getPassword(), - authentication.getCredentials().toString(), user)) + 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/encoding/BaseDigestPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java new file mode 100644 index 0000000000..e2c9f20984 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java @@ -0,0 +1,50 @@ +/* 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.encoding; + +import net.sf.acegisecurity.providers.encoding.*; + + +/** + *

+ * 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. + * + * @param encodeHashAsBase64 DOCUMENT ME! + */ + public void setEncodeHashAsBase64(boolean encodeHashAsBase64) { + this.encodeHashAsBase64 = encodeHashAsBase64; + } + + public boolean getEncodeHashAsBase64() { + return encodeHashAsBase64; + } +} diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java new file mode 100644 index 0000000000..2f3b949950 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java @@ -0,0 +1,64 @@ +/* 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.encoding; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; + + +/** + *

+ * MD5 implementation of PasswordEncoder. + *

+ * + *

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

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public class Md5PasswordEncoder extends BaseDigestPasswordEncoder + implements PasswordEncoder { + //~ Methods ================================================================ + + /* (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 salt) { + String pass1 = "" + encPass; + String pass2 = encodeInternal("" + 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 salt) { + 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/encoding/PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java new file mode 100644 index 0000000000..f577f565e9 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java @@ -0,0 +1,87 @@ +/* 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.encoding; + +import org.springframework.dao.DataAccessException; + + +/** + *

+ * Interface for performing authentication operations on a password, so that + * digest algorithms may be abstracted. + *

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public interface PasswordEncoder { + //~ Methods ================================================================ + + /** + *

+ * Validates a specified 'raw' password against an encoded password + * previously returned form {@link #encodePassword(String, Object)}. The + * raw password will first be encoded, and then both values will be + * compared. + *

+ * + *

+ * The specified salt will potentially be used by the implementation to + * 'salt' the initial value before encoding. If a salt value is provided, + * it must be the same as the value used when calling {@link + * #encodePassword(String, Object)} to produce the first encoded value. + * Note that a specific implementation may choose to ignore the salt + * value, or provide its own. + *

+ * + * @param encPass a pre-encoded password + * @param rawPass a raw password to encode and compare against the + * pre-encoded password + * @param an object optionally used by the implementation to 'salt' the raw + * password before encoding. A null value is legal. + * + * @return DOCUMENT ME! + */ + public boolean isPasswordValid(String encPass, String rawPass, + Object saltSource) throws DataAccessException; + + /** + *

+ * Encodes the specified raw password with an implementation specific + * algorithm. This will generally be a one-way message digest such as MD5 + * or SHA, but may also be a plaintext variant which does no encoding at + * all, but rather returns the same password it was fed. The latter is + * useful to plug in when the original password must be stored as-is. + *

+ * + *

+ * The specified salt will potentially be used by the implementation to + * 'salt' the initial value before encoding, in order to prevent + * dictionary attacks. If a salt value is provided, the same salt value + * must be use when calling the {@link #isPasswordValid(String, String, + * Object)} function. Note that a specific implementation may choose to + * ignore the salt value, or provide its own. + *

+ * + * @param rawPass the password to encode + * @param an object optionally used by the implementation to 'salt' the raw + * password before encoding. A null value is legal. + * + * @return DOCUMENT ME! + */ + public String encodePassword(String rawPass, Object salt) + throws DataAccessException; +} diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java new file mode 100644 index 0000000000..b5f8da9b8d --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java @@ -0,0 +1,68 @@ +/* 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.encoding; + +/** + *

+ * Plaintext implementation of PasswordEncoder. + *

+ * + * @author colin sampaleanu + * @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(java.lang.String, java.lang.String, java.lang.Object) + */ + public boolean isPasswordValid(String encPass, String rawPass, Object salt) { + String pass1 = "" + encPass; + String pass2 = "" + rawPass; + + if (!ignorePasswordCase) { + return pass1.equals(pass2); + } else { + return pass1.equalsIgnoreCase(pass2); + } + } + + /* (non-Javadoc) + * @see net.sf.acegisecurity.providers.dao.PasswordEncoder#encodePassword(java.lang.String, java.lang.Object) + */ + public String encodePassword(String rawPass, Object salt) { + return rawPass; + } +} diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java new file mode 100644 index 0000000000..1ad7a8737b --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java @@ -0,0 +1,64 @@ +/* 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.encoding; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; + + +/** + *

+ * SHA implementation of PasswordEncoder. + *

+ * + *

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

+ * + * @author colin sampaleanu + * @version $Id$ + */ +public class ShaPasswordEncoder extends BaseDigestPasswordEncoder + implements PasswordEncoder { + //~ Methods ================================================================ + + /* (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 salt) { + String pass1 = "" + encPass; + String pass2 = encodeInternal("" + 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 salt) { + 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 057128acf2..d0e52197a8 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java +++ b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java @@ -36,9 +36,9 @@ public interface AuthenticationDao { /** * 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.. + * 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/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java index eeeac4afc7..1b77d87a0e 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -37,7 +37,6 @@ import org.springframework.dao.DataRetrievalFailureException; * @version $Id$ */ public class DaoAuthenticationProviderTests extends TestCase { - //~ Methods ================================================================ public final void setUp() throws Exception { diff --git a/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java b/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java index 12a2dc33ff..ef2d0d1c07 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/MD5PasswordEncoderTest.java @@ -12,10 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.sf.acegisecurity.providers.dao; import junit.framework.TestCase; +import net.sf.acegisecurity.providers.encoding.*; + + /** *

* TestCase for PlaintextPasswordEncoder. @@ -25,23 +29,22 @@ import junit.framework.TestCase; * @version $Id$ */ public class MD5PasswordEncoderTest extends TestCase { + //~ Methods ================================================================ - 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); - } + 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 index 8646d4dda8..d4935312d4 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/PlaintextPasswordEncoderTest.java @@ -12,10 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.sf.acegisecurity.providers.dao; import junit.framework.TestCase; +import net.sf.acegisecurity.providers.encoding.*; + + /** *

* TestCase for PlaintextPasswordEncoder. @@ -25,35 +29,36 @@ import junit.framework.TestCase; * @version $Id$ */ public class PlaintextPasswordEncoderTest extends TestCase { + //~ Methods ================================================================ - public void testBasicFunctionality() { - PlaintextPasswordEncoder pe = new PlaintextPasswordEncoder(); + 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)); + String raw = "abc123"; + String rawDiffCase = "AbC123"; + String badRaw = "abc321"; - // 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 + String encoded = raw; + assertTrue(pe.isPasswordValid(encoded, raw, null)); // no SALT source + assertFalse(pe.isPasswordValid(encoded, badRaw, null)); - // 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)); - } + // 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)); -} \ No newline at end of file + // 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)); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java b/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java index 67f1707dfa..bd6ca30354 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/SHAPasswordEncoderTest.java @@ -12,36 +12,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.sf.acegisecurity.providers.dao; import junit.framework.TestCase; +import net.sf.acegisecurity.providers.encoding.*; + + /** *

- * TestCase for SHAPasswordEncoder. + * TestCase for ShaPasswordEncoder. *

* * @author colin sampaleanu * @version $Id$ */ public class SHAPasswordEncoderTest extends TestCase { + //~ Methods ================================================================ - 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); - - } + 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/samples/contacts/src/main/java/sample/contact/ClientApplication.java b/samples/contacts/src/main/java/sample/contact/ClientApplication.java index b1e4e80dad..319b003640 100644 --- a/samples/contacts/src/main/java/sample/contact/ClientApplication.java +++ b/samples/contacts/src/main/java/sample/contact/ClientApplication.java @@ -30,7 +30,7 @@ import java.util.Map; /** * Demonstrates accessing the {@link ContactManager} via remoting protocols. - * + * *

* Based on Spring's JPetStore sample, written by Juergen Hoeller. *

diff --git a/test/acegisecuritytest.properties b/test/acegisecuritytest.properties index 832a797a7f..87a3e7d5a6 100644 --- a/test/acegisecuritytest.properties +++ b/test/acegisecuritytest.properties @@ -1,5 +1,5 @@ #HSQL database -#Thu Apr 15 12:20:59 EDT 2004 +#Thu Apr 15 23:43:47 EDT 2004 sql.strict_fk=true readonly=false sql.strong_fk=true