2010-04-27 11 views
8

Tôi đang triển khai ứng dụng bằng bảo mật mùa xuân 3.0.2 với đăng nhập và đăng ký OpenId. Tôi có thể đăng nhập thành công, nhưng nếu người dùng không đăng ký tôi muốn làm:Xác thực OpenId và đăng ký tự động với Spring Security 3.0.2

1) Nhận một số thuộc tính OpenId như email và tên.
2) Hiển thị cho người dùng mẫu đăng ký chỉ với hai trường này và URI OpenId đã được điền đầy đủ.

Tôi đã tìm kiếm rất nhiều nhưng tôi không tìm thấy cách "thực hiện". Tôi tự hỏi nếu một số u có thể đưa ra một giải pháp để thực hiện chiến lược này trong ứng dụng của tôi.

Xin cảm ơn trước.

Trả lời

5

Bạn không thể hiển thị email và tên trước khi người dùng đăng ký/đăng nhập, vì anh ấy phải cho phép ứng dụng truy cập hồ sơ của mình trước tiên. Bạn có thể cho anh ta trang này với openid mình, mail vv sau ông logged in

Xác định mà các thuộc tính bạn muốn sử dụng:.

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

Và sau đó truy cập vào các thuộc tính, sau khi người dùng đã đăng nhập :

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

Hãy xem example from the spring repositoryOpenId Support Documentation.

+0

@dude : Tôi có vấn đề tương tự và đã sử dụng câu trả lời do bạn đề xuất ... nhưng mã dường như không hoạt động .... hãy xem http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is -không-làm việc-xuân-securit y – aProgrammer

0

Đó không phải được thực hiện trong an ninh mùa xuân < 3.1

Tuy nhiên bạn có thể sử dụng một cách giải quyết với apectJ. Xác định các khía cạnh sau:

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

và đăng ký nó trong aop.xml của bạn:

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

Sau đó, trong UserDetailsService của bạn, bạn có thể truy cập vào OpenID thuộc tính như sau:

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

Hãy nhớ rằng bạn vẫn cần nói mùa xuân rằng bạn muốn thuộc tính email bằng cách sử dụng thẻ ** **. – Florian