2010-04-27 112 views
8

我正在使用Spring Security 3.0.2使用OpenId登錄和註冊來實現應用程序。 我可以成功登錄,但如果用戶沒有註冊我想要做的:OpenId身份驗證和使用Spring Security 3.0.2進行自動註冊

1)獲取一些OpenId屬性,如電子郵件和名稱。
2)向用戶顯示只有這兩個字段和填充的OpenId URI的註冊表單。

我一直在尋找很多,但是我沒有找到這樣做的「優雅」方式。 我不知道你是否可以在我的應用中使用解決方案來實現這個策略。

在此先感謝。

回答

5

在用戶註冊/登錄之前,您不能顯示電子郵件和姓名,因爲他必須先允許應用程序訪問他的個人資料。你可以給他看這個頁面,其OpenID,郵件等他登錄

定義你想要的屬性,使用方法:

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

,然後訪問屬性,用戶在登錄後, :

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

看一看的example from the spring repositoryOpenId Support Documentation

+0

@dude :我有類似的問題,並使用你所提出的答案...但代碼似乎並不工作....看看http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is - 不是 - 工作 - 彈簧 - SECURIT y – aProgrammer 2011-08-29 12:09:26

0

,是不是在春季安全< 3.1

實現。然而,您可以使用一種變通方法與apectJ。定義以下方面:

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

,並在您註冊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> 
在你的UserDetailsS​​ervice

然後,您可以訪問OpenID的屬性如下:

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

請記住,您仍然需要使用** **標籤告訴spring您需要email屬性。 – Florian 2011-11-20 10:18:41

相關問題