2012-09-18 22 views
5

Ésta es mi escenario:SpringSecurity - Custom autenticación automática

  • una aplicación Web realizan una especie de SSO para muchas aplicaciones
  • usuario conectado que haga clic en un enlace y la aplicación hace un post con información de usuario (nombre, pwd [inútiles], roles) hacia la correcta aplicación
  • estoy implementando SpringSecurity en una de estas aplicaciones para beneficiarse de su poder (autoridades de la sesión, los métodos proporcionados por sus clases, etc.)

Entonces, necesito desarrollar un filtro personalizado - Supongo - que es capaz de recuperar información del usuario de la solicitud, recuperar de la base de datos, a través de un personalizado DetailsUserService, más información sobre el usuario (correo electrónico, etc ...) y luego realizar la autenticación de ese usuario, de acuerdo con la función recuperada de la solicitud.

Estaba mirando Pre-Authentication filtros, pero no estoy seguro de que sea la opción correcta. Parece que se espera que esos objetos se usen cuando el principal ya está en sesión, puesto por algún machanismo de autenticación anterior (¿es correcto?).

creo que, una vez identificado el filtro correcto, debería necesitar realizar dentro de algo como:

GrantedAuthority[] ga= new GrantedAuthority[1]; 
ga[0] = new GrantedAuthorityImpl(myUser.getRole()); 

SecurityContext sc = SecurityContextHolder.getContext(); 
Authentication a = new UsernamePasswordAuthenticationToken(userName, userPwd, ga); 
a = authenticationManager.authenticate(a); 
sc.setAuthentication(a); 

¿Es la dirección correcta para resolver mi problema? ¿Tiene sugerencias para ayudarme a encontrar lo que falta?

Gracias a todos,

Luca

ADEMÁS:

Hola Xearxess! Perdón por molestarlo de nuevo, pero parece que la traducción de su código de acuerdo con SpringSecurity 2.0.4 es más difícil de lo que pensaba: S El problema es el XML ... Intenté una configuración diferente pero siempre me encontré con problemas de espacio de nombres, atributos perdidos , etc ...

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> 

    <security:http> 
     <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
     <security:logout logout-url="/logout" logout-success-url="http://milan-ias-vs.usersad.everis.int/DMTest/" invalidate-session="true" /> 
     <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthenticatedProcessingFilter" /> 
    </security:http> 

    <bean id="preAuthenticatedProcessingFilter" class="it.novartis.ram.authentication.PreAuthenticatedProcessingFilter"> 
     <custom-filter position="PRE_AUTH_FILTER"/> 
     <property name="authenticationManager" ref="authenticationManager" /> 
    </bean> 

    <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
     <property name="preAuthenticatedUserDetailsService"> 
      <bean class="it.novartis.ram.authentication.PreAuthenticatedUserDetailsService" /> 
     </property> 
    </bean> 

    <security:authentication-manager alias="authenticationManager"> 
     <security:authentication-provider ref="preauthAuthProvider" /> 
    </security:authentication-manager> 

</beans> 

Las 2 filas que hacen referencia a elementos CUSTOM-filtro son dos intentos diferentes, tanto de ellos firmaron como un error. ¿Cómo puedo especificar la posición de mi filtro como una propiedad?

También la referencia del proveedor de autenticación en la definición del administrador de autenticación está marcada como error. Creo que también debo especificarlo como una propiedad, ¿no?

espero que me puedan dar el último empujón;) Gracias de nuevo,

Luca

Respuesta

11

Sí, escenarios pre-autenticación se exactamente lo que están buscando.

Parece que se espera que los objetos que se utilizará cuando el director ya está en sesión, planteada por algunos anterior machanism autenticación (¿es correcto?).

No es realmente, usted puede utilizar la autenticación previa para crear PreAuthenticatedAuthenticationToken de la solicitud, como desee. Solo do few things I described in another question.

Primera extender AbstractPreAuthenticatedProcessingFilter para obtener nombre de usuario y las funciones de solicitud:

public class MyPreAuthenticatedProcessingFilter 
    extends AbstractPreAuthenticatedProcessingFilter { 

    public MyPreAuthenticatedProcessingFilter(
     AuthenticationManager authenticationManager) { 
    setAuthenticationDetailsSource(new MyAuthenticationDetailsSource()); 
    } 

    @Override 
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
    return "Anonymous"; 
    } 

    @Override 
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
    return "N/A"; 
    } 

    public static class MyAuthenticationDetailsSource implements 
     AuthenticationDetailsSource<HttpServletRequest, MySessionUserDetails> { 
    // roles probably should be encrypted somehow 
    static final String ROLES_PARAMETER = "pre_auth_roles"; 

    @Override 
    public MySessionUserDetails buildDetails(HttpServletRequest req) { 
     // create container for pre-auth data 
     return new MySessionUserDetails(req.getParameter(ROLES_PARAMETER)); 
    } 
    } 
} 

MySessionUserDetails clase se dividirá la primavera con papeles a la lista de SimpleGrantedAuthority o cualquier otra aplicación GrantedAuthority. Además, se recomienda Lista y es superior a GrantedAuthority[].

En segundo lugar, aplicar AuthenticationUserDetailsService:

public class MyPreAuthenticatedUserDetailsService implements 
    AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { 

    @Override 
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) 
     throws UsernameNotFoundException { 
    MySessionUserDetails sessionUserDetails = 
     (MySessionUserDetails) token.getDetails(); 
    List<GrantedAuthority> authorities = sessionUserDetails.getAuthorities(); 
    return new User(token.getName(), "N/A", true, true, true, true, authorities); 
    } 
} 

Luego, en el código XML conectar bloques juntos:

<security:http use-expressions="true"> 
    <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
    <security:custom-filter position="PRE_AUTH_FILTER" 
     ref="myPreAuthenticationFilter" /> 
</security:http> 

<bean id="myPreAuthenticationFilter" 
    class="com.example.MyPreAuthenticatedProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
</bean> 

<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
    <property name="preAuthenticatedUserDetailsService"> 
    <bean class="com.example.MyPreAuthenticatedUserDetailsService" /> 
    </property> 
</bean> 

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider ref="preauthAuthProvider" /> 
</security:authentication-manager> 

y listo! Debe haber autenticado el User principal para usar en su aplicación.

El código I escrito aquí requiere Spring Security 3.1, que recomiendo encarecidamente si está a punto de usarlo (se requiere Spring 3.0.7+). ¡También, Spring Security reference manual es tu amigo!

+0

Muchas gracias Xaerxess! Desafortunadamente estamos atrapados con Spring 2.5.6 y Spring Security 2.0.4, pero sus sugerencias me ayudarán;) – Dolfiz

+0

Es una pena, Spring 3 es mucho mejor, más genérico y tiene una gran documentación. Pero gran cantidad de código anterior puede ser backported a 2.X (sin genéricos, por ejemplo). – Xaerxess

+0

¡Es una pena! Pero el código que escribiste me ayudará. Gracias de nuevo y pase un buen rato con su bebé;) – Dolfiz

8

Para completar, en Spring Security 4 cosas han cambiado ligeramente. Por ejemplo, la configuración de Java es muy recomendable. De esta manera, es más fácil de integrar con Spring Boot.

Sigue la configuración de Java que es equivalente a la configuración XML dada en las respuestas anteriores.

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.addFilterBefore(customAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class) 
      .authenticationProvider(preauthAuthProvider()) 
      .authorizeRequests() 
      .anyRequest().authenticated(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(preauthAuthProvider()); 
    } 

    @Bean 
    public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { 
     PreAuthenticatedAuthenticationProvider preauthAuthProvider = 
      new PreAuthenticatedAuthenticationProvider(); 
       preauthAuthProvider.setPreAuthenticatedUserDetailsService(
        userDetailsServiceWrapper()); 
     return preauthAuthProvider; 
    } 

    @Bean 
    public OnlyRolesPreAuthenticatedUserDetailsService userDetailsServiceWrapper() { 
     OnlyRolesPreAuthenticatedUserDetailsService service = 
      new MyPreAuthenticatedUserDetailsService(); 
     return service; 
    } 

    @Bean 
    public MyPreAuthenticatedProcessingFilter customAuthFilter() throws Exception { 
     MyPreAuthenticatedProcessingFilter filter = new MyPreAuthenticatedProcessingFilter(); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 
} 

creo que el código anterior vale la pena, porque los ejemplos en Internet son muy básicas y la documentación de Primavera carece de tales detalles.

+0

¡Muchas gracias! No he encontrado en ninguna parte una explicación con la configuración en Java – encastellano

+0

Me complace ayudarte. –