example ejemplos dependencias con autenticacion authentication passwords spring-security salt

authentication - ejemplos - Autenticación personalizada Spring Security y codificación de contraseña



spring security http (3)

¿Hay algún tutorial o alguien tiene indicaciones sobre cómo hacer lo siguiente con Spring-Security?

Tarea:

Necesito obtener la sal de mi base de datos para el nombre de usuario de autenticación y usarla para encriptar la contraseña provista (desde la página de inicio de sesión) para compararla con la contraseña encriptada almacenada (también conocida como autenticar al usuario).

Información Adicional:

Yo uso una estructura de base de datos personalizada. Un objeto UserDetails se crea a través de un UserDetailsService personalizado que a su vez utiliza un DAOProvider personalizado para obtener la información de la base de datos.

mi archivo security.xml hasta el momento:

<authentication-manager> <authentication-provider user-service-ref="userDetailsService"> </authentication-provider> </authentication-manager>

ahora supongo que necesitaré

<password-encoder hash="sha" />

pero que mas? ¿Cómo digo a la seguridad de primavera que use la sal proporcionada por la base de datos para codificar la contraseña?

editar :

Encontré esta publicación de SO para ser informativa pero no suficiente: si defino una fuente de sal en mi xml para ser utilizada por el codificador de contraseña, así:

<password-encoder ref="passwordEncoder"> <salt-source ref="saltSource"/> </password-encoder>

Tendré que escribir un SaltSource personalizado para usar mi sal personalizada. Pero eso no se encuentra dentro del objeto UserDetails . Asi que...

Alternativa 1:

¿Puedo usar una implementación personalizada de UserDetails que podría tener la propiedad salt?

<beans:bean id="saltSource" class="path.to.MySaltSource" p:userPropertyToUse="salt"/>

y

@Service("userDetailsService") public class UserDetailsServiceImpl implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { // ... return buildUserFromAccount(account); } @Transactional(readOnly = true) UserDetailsImpl buildUserFromAccount(Account account){ // ... build User object that contains salt property }

Clase de usuario personalizada:

public class UserDetailsImpl extends User{ // ... private String salt; public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } }

security.xml:

<authentication-manager> <authentication-provider user-service-ref="userDetailsService"> <password-encoder hash="sha"> <salt-source ref="saltSource"/> </password-encoder> </authentication-provider> </authentication-manager> <beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/>


Alternativa 2:

De lo contrario, tendría que inyectar mi cuentaDAO en SaltSource para extraer la sal de un nombre de userName dado de la base de datos.

PERO: ¿Cómo llama Spring Security al SaltSource ? Siempre con saltSource.getSalt(userDetails) ?

Entonces solo tendría que asegurarme de que SaltSource utiliza userDetails.accountName en mi accountDAO para recuperar el salt.

Edit2:

Acabo de enterarme de que mi enfoque es ... herencia ... :( Así que supongo que usaré el StandardPasswordEncoder (que todavía tengo que averiguar cómo usarlo exactamente).

Por cierto: Implementé la primera opción con una clase UserDetails personalizada que ampliaba la clase User y simplemente agregaba una propiedad salt que luego se pasaba a SaltSource como userPropertyToUse tal como se propuso en la publicación SO mencionada en Edit 1 ...

EDIT 3:

Acabo de utilizar el StandardPasswordEncoder, así que dejaré algunos punteros aquí:

Use el StandardPasswordEncoder para Autenticación:

<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"> </beans:bean> <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> <password-encoder ref="encoder" /> </authentication-provider> </authentication-manager>

Esto requiere el módulo spring-security-crypto en la versión 3.1.0.RC? por lo que sé. No se pudo encontrar ningún repositorio que tenga un 3.0. versión (aunque en alguna parte tenía las versiones enumeradas que incluían 3.0.6 y así sucesivamente). También la documentación habla sobre la seguridad de la primavera 3.1, así que pensé, iré con eso.

Al crear un usuario (para mí solo un administrador puede hacer eso), solo uso

StandardPasswordEncoder encoder = new StandardPasswordEncoder(); String result = encoder.encode(password);

y he terminado.

La seguridad de primavera creará al azar una sal y la agregará a la cadena de contraseña antes de almacenarla en la base de datos, por lo que ya no se necesita una columna de sal .

Sin embargo, también se puede proporcionar una sal global como argumento constructor ( new StandardPasswordEncoder("12345"); ), pero no sabía cómo configurar mi configuración de seguridad para recuperar ese valor de un bean en lugar de suministrar una cadena estática con <constructor-arg name="secret" value "12345" /> . Pero no sé cuánto se necesita de todos modos.


Marcaré esto como respondido, ya que resolví mi problema y no se dieron otros comentarios o respuestas:

Edit 1 - La Alternativa 1 responde la pregunta original

PERO tuve que aprender que el salado de contraseñas personalizado es un enfoque heredado que ya no es necesario en Spring Security 3.1, como describo en

Edit 3 donde dejé algunos consejos sobre cómo usar el StandardPasswordEncoder para Sales automatizadas que se almacenan con la contraseña.


Para recuperar la sal global de un frijol, use el Lenguaje de Expresión de Resorte o SpEL.

<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"> <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/> </beans:bean>