2010-04-27 17 views
8

Estoy implementando una aplicación que utiliza spring security 3.0.2 con inicio de sesión e inscripción en OpenId. Puedo iniciar sesión con éxito, pero si el usuario no está registrado quiero hacerlo:Autenticación OpenId y registro automático con Spring Security 3.0.2

1) Obtenga algunos atributos de OpenId como el correo electrónico y el nombre.
2) Muestre al usuario un formulario de registro con solo estos dos campos y llene el URI de OpenId.

He estado buscando mucho pero no he encontrado una manera "ellegante" de hacer esto. Me pregunto si algunos de ustedes pueden presentar una solución para implementar esta estrategia en mi aplicación.

Gracias de antemano.

Respuesta

5

No puede mostrar el correo electrónico y el nombre antes de que el usuario se haya registrado/inicie él mismo, ya que primero debe permitir que la aplicación acceda a su perfil. Se le puede mostrar esta página con su OpenID, correo, etc. después se registra en

Definir los atributos que desea utilizar:.

<openid-login login-page="/openidlogin.jsp" authentication-failure-url="/openidlogin.jsp?login_error=true"> 
    <attribute-exchange> 
    <openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" count="2"/> 
    <openid-attribute name="name" type="http://schema.openid.net/namePerson/friendly" /> 
    </attribute-exchange> 
</openid-login> 

y luego acceder a los atributos, después de que el usuario ha iniciado sesión :

OpenIDAuthenticationToken token = (OpenIDAuthenticationToken)SecurityContextHolder.getContext().getAuthentication(); 
List<OpenIDAttribute> attributes = token.getAttributes(); 

Tener un vistazo a la example from the spring repository y el OpenId Support Documentation.

+0

@dude : Tengo el problema similar y he utilizado la respuesta sugerida por usted ... pero el código no parece funcionar ... eche un vistazo a http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is -no-trabajando-primavera-seguridad y – aProgrammer

0

que no está implementado en la primavera de Seguridad < 3.1

Sin embargo se puede utilizar una solución con apectJ. Definir el siguiente aspecto:

package org.acoveo.spring.utils; 
@Aspect 
public class OpenIDSpringAuthenticationHackAspect { 
    static ThreadLocal<Authentication> authHolder = new ThreadLocal<Authentication>(); 
    @Around(value="execution(* org.springframework.security.openid.OpenIDAuthenticationProvider.authenticate(..))") 
    public Object around(ProceedingJoinPoint jp) throws Throwable { 
     try { 
      Authentication auth = (Authentication) jp.getArgs()[0]; 
      authHolder.set(auth); 
      Object returnVal = jp.proceed(); 
      authHolder.set(null); 
      return returnVal; 
     }catch(Throwable e) { 
      System.out.println("Exception while running OpenIDSpringAuthenticationHackAspect"); 
      e.printStackTrace(); 
      return null; 
     } 
    } 
    public static Authentication getTransientAuthentication() { 
     return authHolder.get(); 
    } 
} 

y registrarlo en su aop.xml:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> 
<aspectj> 
    <weaver options="-showWeaveInfo -verbose" /> 
    <weaver> 
     <include within="org.springframework.security.openid..*" /> 
     <!-- This is required to make the spring instrument javaagent work with hibernate CGLIB 
     --> 
     <exclude within="*..*CGLIB*" /> 
    </weaver> 
    <aspects> 
     <aspect name="org.acoveo.spring.utils.OpenIDSpringAuthenticationHackAspect" /> 
    </aspects> 
</aspectj> 

Luego, en su UserDetailsService, puede acceder a los atributos de OpenID de la siguiente manera:

public UserDetails loadUserByUsername(String username, boolean includeTemporary) throws UsernameNotFoundException, DataAccessException { 
    Authentication auth = OpenIDSpringAuthenticationHackAspect.getTransientAuthentication(); 
    if(auth != null && auth instanceof OpenIDAuthenticationToken) { 
     // First try to find the user by their openid email address 
     OpenIDAuthenticationToken openIdToken = (OpenIDAuthenticationToken)auth; 
     String email = null; 
     for(OpenIDAttribute attr : openIdToken.getAttributes()) { 
      if("email".equals(attr.getName()) && attr.getValues() != null && !attr.getValues().isEmpty()) { 
       email = attr.getValues().get(0); 
       break; 
      } 
     } 
     // TODO retrieve and return user 
+0

Recuerde que aún necesita decirle a la primavera que desea el atributo de correo electrónico utilizando la etiqueta ** **. – Florian

Cuestiones relacionadas