2010-04-27 16 views
8

Sto implementando un'app utilizzando spring security 3.0.2 con accesso OpenId e registrazione. Posso accedere con successo, ma se l'utente non è registrato voglio fare:Autenticazione OpenId e registrazione automatica con Spring Security 3.0.2

1) Ottieni alcuni attributi OpenID come email e nome.
2) Mostra all'utente un modulo di registrazione con solo questi due campi e l'URI OpenId pieno.

Ho cercato molto ma non ho trovato un modo "ellegante" per farlo. Mi chiedo se alcuni di voi possano uscire con una soluzione per implementare questa strategia nella mia app.

Grazie in anticipo.

risposta

5

Non è possibile visualizzare l'e-mail e il nome prima che l'utente si sia registrato/login, poiché deve consentire all'app di accedere prima al suo profilo. Lo si può mostrare questa pagina con il suo OpenID, posta ecc dopo ha registrato nel

Definire quali gli attributi che si desidera utilizzare.

<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> 

E poi accedere agli attributi, dopo che l'utente ha effettuato l'accesso :

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

Date un'occhiata al example from the spring repository, e il OpenId Support Documentation.

+0

@dude : Ho il problema simile e ho usato la risposta suggerita da voi ... ma il codice non sembra funzionare .... date un'occhiata a http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is -non-lavoro-molla-securit y – aProgrammer

0

che non è implementata in sicurezza primavera < 3.1

Tuttavia è possibile utilizzare una soluzione con apectJ. Definire il seguente aspetto:

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(); 
    } 
} 

con registrazione nel vostro 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> 

Poi, nel tuo UserDetailsService, è possibile accedere attributi OpenID come segue:

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

Ricorda che devi ancora dire a primavera che vuoi l'attributo email usando il tag ** **. – Florian

Problemi correlati