2010-04-27 12 views
8

Ich implementiere eine App mit Spring Security 3.0.2 mit OpenId Login und Registrierung. Ich kann erfolgreich anmelden, aber wenn der Benutzer nicht registriert ist, möchte ich Folgendes tun:OpenId Authentifizierung und automatische Registrierung mit Spring Security 3.0.2

1) Erhalten Sie einige OpenId-Attribute wie E-Mail und Name.
2) Zeigen Sie dem Benutzer ein Registrierungsformular mit nur diesen beiden Feldern und der OpenId URI gefüllt.

Ich habe viel gesucht, aber ich fand keine "ellegant" Art, dies zu tun. Ich frage mich, ob einige von Ihnen mit einer Lösung kommen können, um diese Strategie in meiner App zu implementieren.

Vielen Dank im Voraus.

Antwort

5

Sie können die E-Mail und den Namen nicht anzeigen, bevor sich der Benutzer selbst registriert/angemeldet hat, da er der App zunächst erlauben muss, auf sein Profil zuzugreifen. Sie können ihm diese Seite mit seinem openid zeigen, Post usw. nach er angemeldet

definieren, welche Attribute Sie verwenden möchten.

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

Und dann die Attribute zugreifen, nachdem sich der Benutzer angemeldet hat Haben

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

einen Blick auf die example from the spring repository und die OpenId Support Documentation:.

+0

@dude : Ich habe das ähnliche Problem und habe die von Ihnen vorgeschlagene Antwort verwendet ... aber der Code scheint nicht zu funktionieren .... werfen Sie einen Blick auf http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is -nicht-Arbeitsfeder-Securit y – aProgrammer

0

, die nicht im Frühjahr Sicherheit implementiert wird < 3,1

auch immer Sie eine Abhilfe mit apectJ verwenden kann. Definieren Sie den folgenden Aspekt: ​​

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

und registrieren Sie es in Ihrem 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> 

Dann in Ihrem UserDetailsService, können Sie die OpenID Zugriff auf Attribute wie folgt:

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

Denken Sie daran, dass Sie Spring weiterhin mitteilen müssen, dass Sie das E-Mail-Attribut mit dem ** ** -Tag verwenden möchten. – Florian