8

Я реализую приложение с использованием Spring Security 3.0.2 с регистрацией и регистрацией OpenId. Я могу войти в систему успешно, но если пользователь не зарегистрирован, я хочу:Аутентификация OpenId и автоматическая регистрация с Spring Security 3.0.2

1) Получите некоторые атрибуты OpenId, такие как электронная почта и имя.
2) Покажите пользователю регистрационную форму только с этими двумя полями и URI OpenId.

Я много искал, но я не нашел «ellegant» способ сделать это. Интересно, может ли кто-нибудь из вас выйти с решением для реализации этой стратегии в моем приложении.

Заранее спасибо.

ответ

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 repository и OpenId Support Documentation.

+0

@dude : У меня есть аналогичная проблема, и я использовал предложенный вами ответ ... но код не работает. Посмотрите http://stackoverflow.com/questions/7228733/openid-attribute-exchange-is -на работоспособной-весна-SecurIT y – aProgrammer

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> 

Тогда в вашем UserDetailsService, вы можете получить доступ атрибуты 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

Помните, что вам все равно нужно сообщить весне, что вы хотите использовать атрибут электронной почты, используя тег ** **. – Florian

Смежные вопросы