OpenId authentication and automatic registration with Spring Security 3.0.2

喜夏-厌秋 提交于 2019-12-18 15:54:05

问题


I'm implementing an app using spring security 3.0.2 with OpenId login and registration. I can login succesfully, but if the user isn't registered i want to do:

1) Get some OpenId attributes like email and name.
2) Show to the user a registration form with just these two fields and the OpenId URI filled.

I've been searching a lot but i didn't find an "ellegant" way of doing this. I wonder if some of u can come out with a solution to implement this strategy in my app.

Thanks in advance.


回答1:


You can't show the email and name before the user has registered/login himself, since he has to allow the app to access his profile first. You can show him this page with his openid, mail etc after he logged in.

Define which attributes you want to use:

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

And then access the attributes, after the user has logged in:

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

Have a look at the example from the spring repository, and the OpenId Support Documentation.




回答2:


That is not implemented in Spring security < 3.1

However you can use a workaround with apectJ. Define the following aspect:

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

and register it in your 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>

Then in your UserDetailsService, you can access the OpenID attributes as follows:

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


来源:https://stackoverflow.com/questions/2724123/openid-authentication-and-automatic-registration-with-spring-security-3-0-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!