仔细看过Spring BlazeDS Integration文档,我们知道,配置spring security其实很简单。
如下:
org.springframework.flex.security3.SpringSecurityLoginCommand 类,该类存在spring-flex-core-1.5.2.RELEASE.jar中,
之前提到过,等flex ui调用login api,请求会进入SpringSecurityLoginCommand.doAuthentication(String username, Object credentials)方法
我们来看看其具体实现:
public Principal doAuthentication(String username, Object credentials) {
HttpServletRequest request = FlexContext.getHttpRequest();
HttpServletResponse response = FlexContext.getHttpResponse();
try {
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, extractPassword(credentials));
setDetails(request, authRequest);
Authentication authentication = this.authManager.authenticate(authRequest);
if (authentication != null) {
if (!isPerClientAuthentication() && request != null && response != null) {
this.sessionStrategy.onAuthentication(authentication, request, response);
this.rememberMeServices.loginSuccess(request, response, authentication); //注意这里
}
SecurityContextHolder.getContext().setAuthentication(authentication);
}
return authentication;
} catch (AuthenticationException ex) {
SecurityContextHolder.clearContext();
if (request != null && response != null && !isPerClientAuthentication()) {
this.rememberMeServices.loginFail(request, response);
}
throw ex;
}
}
可见此方法,让flex的login api 和spring sceurity 做了集成。让即使是flex ui传递过来的login请求也会走入到rememberMeServices当中去。
所以可以在rememberMeServices里做文章,找到用户登录成功后的切入点去,编写特殊逻辑。
修改security-config.xml:
自定义的rememberMeServices如下:
package test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.samples.contact.IContactDAO;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
public class MyRememberMeServices extends TokenBasedRememberMeServices {
@Autowired
private IContactDAO contactDAO;
@Override
public void onLoginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
super.onLoginSuccess(request, response, successfulAuthentication);
//SecurityContextHolder.getContext().setAuthentication(successfulAuthentication);
System.out.println("Login Success:"+ contactDAO.findAll()); //登陆成功后,在这里实现自己的特殊逻辑
}
}
注意:
特别注意,如果在MyRememberMeServices.onLoginSuccess()中,所调用的dao方法是,被spring security所管理的话,当通过flex ui 登陆时,是会抱错的:
“Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext"
两个解决办法,任选其一:
PS:org.springframework.flex.security3.SpringSecurityLoginCommand 类 其实也可以继承
然后在自己订制化的LoginCommand类,去找到登陆成功后的切入点。但是本人感觉很复杂,还没研究明白。
具体请看:http://docs.spring.io/spring-flex/docs/1.5.x/reference/html/#custom-login-command