springsecurity扩展session中存放的值
springsecurity扩展session中存放的值
先搞清楚登陆过程的缘由脉络
比较关键的配置文件,在原来的applicationContext-security.xml中增加:
<beans:bean id="authenticationProcessingFilter"
/>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureUrl" value="/login.action?error=true" />
<beans:property name="defaultTargetUrl" value="/user/user.action" />
<beans:property name="usernameParameter" value="j_username" />
<beans:property name="passwordParameter" value="j_password" />
</beans:bean>
登陆时比较关键的就是这个AuthenticationProcessingFilter
其父类方法org.springframework.security.ui.AbstractProcessingFilter中比较关键的方法:
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,Authentication authResult) throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success: " + authResult.toString());
}
SecurityContextHolder.getContext().setAuthentication(authResult);
if (logger.isDebugEnabled()) {
logger.debug("Updated SecurityContextHolder to contain the following Authentication: '" + authResult + "'");
}
if (invalidateSessionOnSuccessfulAuthentication) {
SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
}
String targetUrl = determineTargetUrl(request);
if (logger.isDebugEnabled()) {
logger.debug("Redirecting to target URL from HTTP Session (or default): " + targetUrl);
}
onSuccessfulAuthentication(request, response, authResult);
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
sendRedirect(request, response, targetUrl);
}
这个方法是验证成功后的转向方法,其实里面还有个比较重要的onSuccessfulAuthentication,spring这点还不错,支持了子类中去做事情,不过springsecurity的AuthenticationProcessingFilter没有去做罢了。
那么在上次我已经扩展了org.springframework.security.userdetails.User将id放置到了
SecurityContextHolder.getContext().getAuthentication()里面了,那么我自定义一个AuthenticationProcessingFilter,然后在onSuccessfulAuthentication的时候,将id从SecurityContextHolder中取出来放到session中就行了,思路就是这样。开始动手。
写自定义类CustomerAuthenticationProcessingFilter.java:
package org.springside.examples.miniweb.service.security;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.AbstractProcessingFilter;
import org.springframework.security.ui.FilterChainOrder;
import org.springframework.security.util.TextUtils;
import org.springframework.util.Assert;
import org.springside.examples.miniweb.entity.user.CustomerUserDetails;
public class CustomerAuthenticationProcessingFilter extends
AbstractProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
Authentication authResult) throws IOException {
CustomerUserDetails cu = (CustomerUserDetails)authResult.getPrincipal();
request.getSession().setAttribute("UID", cu.getId());
}
public Authentication attemptAuthentication(HttpServletRequest request)
throws AuthenticationException {
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(
SPRING_SECURITY_LAST_USERNAME_KEY,
TextUtils.escapeEntities(username));
}
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
public String getDefaultFilterProcessesUrl() {
return "/j_spring_security_check";
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource
.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter,
"Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter,
"Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
public int getOrder() {
return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
}
String getUsernameParameter() {
return usernameParameter;
}
String getPasswordParameter() {
return passwordParameter;
}
}
这个类主要就抄写的AuthenticationProcessingFilter,只在里面新增了方法
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,Authentication authResult) throws IOException {
CustomerUserDetails cu = (CustomerUserDetails)authResult.getPrincipal();
request.getSession().setAttribute("UID", cu.getId());
}
将登陆用户的ID放在了UID里面。
页面上user.jsp测试一下:
ID from Session: <%= request.getSession().getAttribute("UID") %> <br/>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureUrl" value="/user/login.do?error=true" />
<beans:property name="defaultTargetUrl" value="/index.jsp" />
<beans:property name="usernameParameter" value="${security.username}" />
<beans:property name="passwordParameter" value="${security.password}" />
</beans:bean> 4 楼 denniswty 2010-10-12 不就直接extend AuthenticationProcessingFilter 再override onSuccessfulAuthentication 更簡單?