![JAR search and dependency download from the Maven repository](/logo.png)
org.jasypt.spring.security.PBEPasswordEncoder Maven / Gradle / Ivy
/*
* =============================================================================
*
* Copyright (c) 2007-2010, The JASYPT team (http://www.jasypt.org)
*
* 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 org.jasypt.spring.security;
import org.jasypt.encryption.pbe.PBEStringEncryptor;
import org.jasypt.exceptions.EncryptionInitializationException;
import org.jasypt.util.text.BasicTextEncryptor;
import org.jasypt.util.text.TextEncryptor;
/**
*
* This class implements the Spring Security (ACEGI)
* org.acegisecurity.providers.encoding.PasswordEncoder
* interface, allowing Spring Security-enabled applications to use JASYPT
* for password encryption.
*
*
* Important: This class allows bi-directional password-based encryption
* of user passwords
* in ACEGI using Jasypt. But please note that passwords should not be
* encrypted in a bi-directional way, but instead as uni-directional
* digests (hashes). Encrypting passwords in a way they can be decrypted
* can be a severe security issue, and should only be considered in legacy
* or complex inter-application integration scenarios.
*
*
* Objects of this class will internally hold either an object of type
* org.jasypt.util.text.TextEncryptor or an object of type
* org.jasypt.encryption.pbe.PBEStringEncryptor (only one of them),
* which should be set by respectively calling
* {@link #setTextEncryptor(TextEncryptor)} or
* {@link #setPbeStringEncryptor(PBEStringEncryptor)}
* after creation. If neither a TextEncryptor nor
* a PBEStringEncryptor are set, a new
* org.jasypt.util.text.BasicTextEncryptor object is
* created and internally used.
*
*
* Important: This implementation ignores any salt provided through
* the interface methods, as the internal Jasypt
* TextEncryptor or PBEStringEncryptor objects normally use a
* random one. This means that salt can be safely passed as
* null.
*
*
* Usage with a TextEncryptor
*
*
* This class can be used like this from your Spring XML resource files:
*
*
* ...
* <!-- Your application may use the TextEncryptor in several places, -->
* <!-- like for example at new user sign-up. -->
* <bean id="jasyptTextEncryptor" class="org.jasypt.util.text.StrongTextEncryptor" >
* <property name="password" value="myPassword" />
* </bean>
* ...
* ...
* <!-- This Spring Security-friendly PasswordEncoder implementation will -->
* <!-- wrap the TextEncryptor instance so that it can be used from -->
* <!-- the security framework. -->
* <bean id="passwordEncoder" class="org.jasypt.spring.security.PBEPasswordEncoder">
* <property name="textEncryptor">
* <ref bean="jasyptTextEncryptor" />
* </property>
* </bean>
* ...
* ...
* <!-- Your DaoAuthenticationProvider will then use it like with any -->
* <!-- other implementation of the PasswordEncoder interface. -->
* <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
* <property name="userDetailsService" ref="userDetailsService"/>
* <property name="passwordEncoder">
* <ref bean="passwordEncoder" />
* </property>
* </bean>
* ...
*
*
* Usage with a PBEStringEncryptor
*
*
* This class can be used like this from your Spring XML resource files:
*
*
* ...
* <!-- Your application may use the PBEStringEncryptor in several places,-->
* <!-- like for example at new user sign-up. -->
* <bean id="jasyptPBEStringEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor" >
* <property name="algorithm" value="PBEWithMD5AndTripleDES" />
* <property name="password" value="myPassword" />
* </bean>
* ...
* ...
* <!-- This Spring Security-friendly PasswordEncoder implementation will -->
* <!-- wrap the PBEStringEncryptor instance so that it can be used from -->
* <!-- the security framework. -->
* <bean id="passwordEncoder" class="org.jasypt.spring.security.PBEPasswordEncoder">
* <property name="pbeStringEncryptor">
* <ref bean="jasyptPBEStringEncryptor" />
* </property>
* </bean>
* ...
* ...
* <!-- Your DaoAuthenticationProvider will then use it like with any -->
* <!-- other implementation of the PasswordEncoder interface. -->
* <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
* <property name="userDetailsService" ref="userDetailsService"/>
* <property name="passwordEncoder">
* <ref bean="passwordEncoder" />
* </property>
* </bean>
* ...
*
*
* This class is thread-safe
*
*
* @since 1.4 (existed since 1.2 as
* org.jasypt.springsecurity.PasswordEncoder)
*
* @deprecated Renamed as org.jasypt.acegisecurity.PBEPasswordEncoder.
* Class will be removed from this package in 1.11.
*
* @author Daniel Fernández
*
*/
public final class PBEPasswordEncoder
implements org.acegisecurity.providers.encoding.PasswordEncoder {
// The text encryptor or PBE string encryptor to be internally used
private TextEncryptor textEncryptor = null;
private PBEStringEncryptor pbeStringEncryptor = null;
private Boolean useTextEncryptor = null;
/**
* Creates a new instance of PBEPasswordEncoder
*/
public PBEPasswordEncoder() {
super();
}
/**
* Sets a text encryptor to be used. Only one of
* setTextEncryptor or setPBEStringEncryptor should be
* called. If both are, the last call will define which method will be
* used.
*
* @param textEncryptor the text encryptor instance to be used.
*/
public void setTextEncryptor(final TextEncryptor textEncryptor) {
this.textEncryptor = textEncryptor;
this.useTextEncryptor = Boolean.TRUE;
}
/**
* Sets a string digester to be used. Only one of
* setTextEncryptor or setPBEStringEncryptor should be
* called. If both are, the last call will define which method will be
* used.
*
* @param pbeStringEncryptor the PBE string encryptor instance to be used.
*/
public void setPbeStringEncryptor(final PBEStringEncryptor pbeStringEncryptor) {
this.pbeStringEncryptor = pbeStringEncryptor;
this.useTextEncryptor = Boolean.FALSE;
}
/**
* Encodes a password. This implementation completely ignores salt,
* as jasypt's TextEncryptor and PBEStringEncryptor
* normally use a random one. Thus, it can be safely passed as null.
*
* @param rawPass The password to be encoded.
* @param salt The salt, which will be ignored. It can be null.
*/
public String encodePassword(final String rawPass, final Object salt) {
checkInitialization();
if (this.useTextEncryptor.booleanValue()) {
return this.textEncryptor.encrypt(rawPass);
}
return this.pbeStringEncryptor.encrypt(rawPass);
}
/**
* Checks a password's validity. This implementation completely ignores
* salt, as jasypt's TextEncryptor and PBEStringEncryptor
* normally use a random one. Thus, it can be safely passed as null.
*
* @param encPass The encrypted password against which to check.
* @param rawPass The password to be checked.
* @param salt The salt, which will be ignored. It can be null.
*/
public boolean isPasswordValid(final String encPass, final String rawPass, final Object salt) {
checkInitialization();
String decPassword = null;
if (this.useTextEncryptor.booleanValue()) {
decPassword = this.textEncryptor.decrypt(encPass);
} else {
decPassword = this.pbeStringEncryptor.decrypt(encPass);
}
if ((decPassword == null) || (rawPass == null)) {
return (decPassword == rawPass);
}
return decPassword.equals(rawPass);
}
/*
* Checks that the PasswordEncoder has been correctly initialized
* (either a text encryptor or a PBE string encryptor has been set).
*/
private synchronized void checkInitialization() {
if (this.useTextEncryptor == null) {
this.textEncryptor = new BasicTextEncryptor();
this.useTextEncryptor = Boolean.TRUE;
} else {
if (this.useTextEncryptor.booleanValue()) {
if (this.textEncryptor == null) {
throw new EncryptionInitializationException(
"PBE Password encoder not initialized: text " +
"encryptor is null");
}
} else {
if (this.pbeStringEncryptor == null) {
throw new EncryptionInitializationException(
"PBE Password encoder not initialized: PBE " +
"string encryptor is null");
}
}
}
}
}