13 changed files with 419 additions and 74 deletions
@ -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.*; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* Convenience base for Digest password encoders |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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; |
||||||
|
} |
||||||
|
} |
||||||
@ -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; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* MD5 implementation of PasswordEncoder. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* A null password is encoded to the same value as an empty ("") password. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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); |
||||||
|
} |
||||||
|
} |
||||||
@ -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; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* Interface for performing authentication operations on a password, so that |
||||||
|
* digest algorithms may be abstracted. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author colin sampaleanu |
||||||
|
* @version $Id$ |
||||||
|
*/ |
||||||
|
public interface PasswordEncoder { |
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 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. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* 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. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 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. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* 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. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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; |
||||||
|
} |
||||||
@ -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; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* Plaintext implementation of PasswordEncoder. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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 |
||||||
|
* <code>false</code>, meaning an exact case match is required. |
||||||
|
* |
||||||
|
* @param ignorePasswordCase set to <code>true</code> 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; |
||||||
|
} |
||||||
|
} |
||||||
@ -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; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* SHA implementation of PasswordEncoder. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* A null password is encoded to the same value as an empty ("") password. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @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); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue