2011-03-19 24 views
15

Estoy usando Spring Security y me gustaría utilizar otro sitio como uno de mis proveedores de autenticación. Tengo un inicio de sesión basado en formulario básico en mi sitio. Quiero tener un enlace en mi sitio que lleve al usuario a un sitio externo donde se conectarán y ese sitio externo luego me enviará una respuesta xml con datos que puedo verificar para ver si hubo un inicio de sesión exitoso. ¡Cualquier ayuda sería muy apreciada!Integre el inicio de sesión único utilizando Spring Security

  1. ¿Cómo se integra ese flujo en Spring Security?
  2. Una vez que reciba la respuesta, ¿cómo puedo iniciar sesión automáticamente en el usuario?

ejemplo, utilizando la guía a continuación:

filtro (no mostrado mis datos proviene de XML de la solicitud):

public class XMLAuthenticationFilter extends AbstractAuthenticationProcessingFilter{ 

    public XMLAuthenticationFilter() { 
     super("/xml_security_check"); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, 
      HttpServletResponse response) throws AuthenticationException, 
      IOException, ServletException { 

      GrantedAuthority[] grantedAuthorities = new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_USER")}; 
      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("userid", "pwd", grantedAuthorities); 
      request.getSession(); 
      token.setDetails(new WebAuthenticationDetails(request)); 
      Authentication authenticatedUser = super.getAuthenticationManager().authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(authenticatedUser); 
      request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); 
      return authenticatedUser; 

} 

}

de autenticación del proveedor:

public class XMLAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{ 
    private UserManager userManager; 
    @Override 
    protected void additionalAuthenticationChecks(UserDetails user, UsernamePasswordAuthenticationToken token) throws AuthenticationException { 

    } 

    @Override 
    protected UserDetails retrieveUser(String userName, UsernamePasswordAuthenticationToken token) throws AuthenticationException { 
     UserDetails user = userManager.getUser(userName); 
     if(user == null){ 
      Users newDCUser = new Users(); 
      newDCUser.setUserId(userName); 
      newDCUser.setRawPassword((String) token.getCredentials()); 
      newDCUser.setFailedLoginAttempts(0); 
      newDCUser.setBeginEffectiveDate(new Date()); 
      newDCUser.setEndEffectiveDate(getEffectiveDate()); 
      userManager.saveUser(newDCUser); 
     } 
     return userManager.loadUserByUsername(userName); 
    } 

    private Date getEffectiveDate(){ 
     Calendar calendar = Calendar.getInstance(); 
     calendar.add(Calendar.YEAR, 10); 
     return calendar.getTime(); 
    } 

    public UserManager getUserManager() { 
     return userManager; 
    } 

    public void setUserManager(UserManager userManager) { 
     this.userManager = userManager; 
    } 
} 

configuración de frijoles:

<bean id="xmlAuthenticationFilter" class="com.dc.api.service.impl.XMLAuthenticationFilter"> 
     <property name="authenticationManager" ref="am" /> 
    </bean> 
    <bean id="xmlAuthenticationProvider" class="com.dc.api.service.impl.XMLAuthenticationProvider"> 
     <property name="userManager" ref="userManager"/> 
    </bean> 
+0

¿El sitio externo usa Spring Security y está en el mismo dominio? – sourcedelica

+0

Hola ericacm, gracias por la respuesta. No a ambas preguntas. Tengo que redirigir a él y luego me hacen una POST con un xml que tengo que analizar y usar sus atributos para decir si el usuario se autenticó con éxito. ¿Algunas ideas? – c12

+0

¿Es SAML o es un XML personalizado exclusivo del sitio? – sourcedelica

Respuesta

8

El enfoque general es:

1) Esquema AbstractAuthenticationToken para los nombres de usuario de XML, vamos a llamarlo XMLAuthenticationToken.

2) Subclase AbstractAuthenticationProcessingFilter y agréguelo a la cadena de filtros después de UsernamePasswordAuthenticationFilter. Debería crear un XMLAuthenticationToken basado en los datos en el XML. Puede usar UsernamePasswordAuthenticationFilter como ejemplo para la estructura general del filtro (es muy probable que sea el filtro que está utilizando actualmente para sus inicios de sesión regulares de Spring Security).

<http> 
    <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/> 
</http> 

El filtro debe establecer un filterProcessesUrl que es diferente de la UsernamePasswordFilter. Esta es la URL a la que el sistema externo publicará el XML. Por ejemplo:

public XmlAuthenticationFilter() { 
    super("/xml_security_check"); 
} 

3) Subclase AbstractUserDetailsAuthenticationProvider. Haga que busque al usuario desde UserDetailsService según la información en el token y luego autentifíquelo. Utilice DaoAuthenticationProvider como ejemplo. Deberá registrar el nuevo proveedor con el AuthenticationManager.

<authentication-manager> 
    <authentication-provider user-service-ref='myUserDetailsService'/> 
    <authentication-provider ref="xmlAuthenticationProvider" /> 
</authentication-manager> 

Usted puede ser capaz de salirse con la reutilización de UsernamePasswordAuthenticationToken (para # 1, que tiene un buen "detalles" mecanismo de extensión) y DaoAuthenticationProvider (o subclasificación de ella) para # 3.

+0

gracias, voy a darle una oportunidad esta noche. aprecia la asistencia – c12

+0

ericacm ¿Cómo configuro mi aplicación para utilizar esta forma de autenticación frente al método basado en el formulario?Tengo un enlace para ambos dentro de la aplicación, pero ¿cómo hace Spring el mapeo? – c12

+0

Al agregar el nuevo filtro a la cadena y agregar el nuevo proveedor al AuthenticationManager. Agregué ejemplos de cómo hacer esto a # 2 y # 3. – sourcedelica

Cuestiones relacionadas