Это не реализовано в Spring security <3.1 </p>
Однако вы можете использовать обходной путь с 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