重新贴出我的自定义rememberMeServices,注意事项,都在注释里面(没事研究一下spring security源码会有新发现的)
package test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.samples.product.IProductDAO;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import flex.messaging.FlexContext;
import flex.messaging.FlexSession;
public class MyRememberMeServices extends TokenBasedRememberMeServices {
private static final String CURRENT_NAME = "current_name";
@Autowired
private IProductDAO securedProductService;
protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
@Override
public void onLoginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
super.onLoginSuccess(request, response, successfulAuthentication);
SecurityContextHolder.getContext().setAuthentication(
successfulAuthentication);
this.afterOnLoginSuccess(request, response, successfulAuthentication);
}
/**
* 当用户已经登出(或者用户从来没有登陆过),再次登陆的时候,会调用此方法
* 进入此方的时候,session已经新建好了,可以自行往session 里面设置相关properties
*
* 在此方法,调用之后,spring security会把 Authentication 设置到session 里, key 是 HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
* 详见:void org.springframework.security.web.context.HttpSessionSecurityContextRepository.SaveToSessionResponseWrapper.saveContext(SecurityContext context)
*
* 所以, 想要获得Authentication 就有两种途径了:
* 1 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
* 2 SecurityContext context = (SecurityContext)httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
* Authentication a = context.getAuthentication();
*
* @param request
* @param response
* @param successfulAuthentication
*/
private void afterOnLoginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
HttpSession session = request.getSession(false); // 该方法,返回的session 一定不为null
System.out.println("login success-----------------session id = "
+ session.getId());
FlexSession flexSession = FlexContext.getFlexSession();
System.out.println("login success-----------------flexSession id = "
+ flexSession.getId());
WebAuthenticationDetails WebAuthenticationDetails = (WebAuthenticationDetails) successfulAuthentication
.getDetails();
System.out
.println("WebAuthenticationDetails.getSessionId()-----------------session id = "
+ WebAuthenticationDetails.getSessionId());
// 登陆成功时,为新创建出来的空session设置properties,
session.setAttribute(CURRENT_NAME, successfulAuthentication.getName());
}
protected UserDetails processAutoLoginCookie(String[] cookieTokens,
HttpServletRequest request, HttpServletResponse response) {
UserDetails userDetails = super.processAutoLoginCookie(cookieTokens,
request, response);
this.afterProcessAutoLoginCookie(userDetails, request, response);
return userDetails;
}
/**
* 当用户已经登陆,直接关闭浏览器,再次又打开浏览器,访问该web应用时候,所走的是: “自动”登陆的流程( “自动”登陆的流程 根cookie有关)
* “自动”登陆的流程, 会调用如下方法:
* Authentication org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(HttpServletRequest request, HttpServletResponse response)
* 如上方法,会调用此方法。
*
* 当进入该方法的时候,此时此刻,还没有任何session(还没有根据客户端的session id 创建新的session)
*
*
* 在此方法,调用之后, 同样的 spring security会把 Authentication 设置到session(如果依然没有session,会自动创建session) 里, key 是 HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
* 详见:void org.springframework.security.web.context.HttpSessionSecurityContextRepository.SaveToSessionResponseWrapper.saveContext(SecurityContext context)
*
* 所以, 想要获得Authentication 就有两种途径了:
* 1 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
* 2 SecurityContext context = (SecurityContext)httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
* Authentication a = context.getAuthentication();
*
* @param userDetails
* @param request
* @param response
*/
private void afterProcessAutoLoginCookie(UserDetails userDetails,
HttpServletRequest request, HttpServletResponse response) {
// HttpSession session = request.getSession(false); // 此语句运行后,session一定是null,
// 因为要在这里往session里面设置一些属性,所以要在此新建session, 如下
HttpSession session = request.getSession(); // 此时必然会创建一个新的session
if (session != null) {
System.out
.println("auto login success-----------------session id = "
+ session.getId());
// “自动”登陆成功时,为新创建出来的空session设置properties,
session.setAttribute(CURRENT_NAME, userDetails.getUsername());
}
FlexSession flexSession = FlexContext.getFlexSession();
if (flexSession != null) {
System.out
.println("auto login success-----------------flexSession id = "
+ flexSession.getId());
}
}
}