Spring-Security笔记9 自定义登录成功后的处理程序及修改默认验证地址

时间:2022-11-15 16:06:30

form-login配置中的authentication-success-handler-ref可以让手动注入登录成功后的处理程序,需要实现AuthenticationSuccessHandler接口。


登录成功之后的相关业务逻辑都可以写这个handler方法中,而不应该在login.do这种方法里写。

login.do应该仅处理验证登录、权限获取。

登录成功之后,使用handler来进行相关业务初始化操作。


先看配置:

<!-- 登录表单设置 -->
<!-- login-page:登录页面 -->
<!-- login-processing-url:自定义的登录提交action名称,需要与登录form中的action保持一致 -->
<!-- authentication-failure-url:登录失败后跳转的页面 -->
<!-- default-target-url:登录成功后跳转的页面,如果配置了authentication-success-handler-ref则不生效 -->
<!-- username-parameter:登录用户名的参数名称,需要与登录form中的input name='username'保持一致 -->
<!-- password-parameter:登录密码的参数名称,需要与登录form中的input name='password'保持一致 -->
<!-- authentication-success-handler-ref:自定义登录成功后的Handler -->
<sec:form-login login-page="/toLogin.do"
login-processing-url="/login.do" authentication-failure-url="/toLogin.do?message=authentication-failure"
authentication-success-handler-ref="customLoginSuccessHandler"
username-parameter="username" password-parameter="password" />


自定义的successHandler

package com.fhzz.core.sercurity.handler;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fhzz.core.sercurity.dao.SysUsersDao;
import com.fhzz.core.sercurity.entity.SysUsers;
import com.fhzz.core.utils.HTTPUtils;

/**
 * @author YangYi
 * 
 */
@Service
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {
	Log logger = LogFactory.getLog(CustomLoginSuccessHandler.class);

	@Value("/toIndex.do")
	private String defaultTargetUrl;
	@Autowired
	private SysUsersDao sysUsersDao;

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		this.saveLoginInfo(request, authentication);
		logger.info("登录成功,即将forward:" + this.defaultTargetUrl);
		// 登录成功之后将SECURITY放入上下文中
		request.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
		request.getRequestDispatcher(this.defaultTargetUrl).forward(request, response);
	}

	private void saveLoginInfo(HttpServletRequest request, Authentication authentication) {
		SysUsers user = (SysUsers) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String ip = HTTPUtils.getIpAddress(request);
		user.setLastLogin(new Date());
		user.setLoginIp(ip);
		logger.info("登录用户:" + user);
		this.sysUsersDao.saveOrUpdateSysUser(user);
	}

}

这个handler 以记录用户登录信息为例,实现了onAuthenticationSuccess方法

实际上这里可以做任何应该与用户一同初始化的工作