Spring Security教程(10)---- 自定義登入成功後的處理程式及修改預設驗證地址
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
form-login配置中的authentication-success-handler-ref可以讓手動注入登入成功後的處理程式,需要實現AuthenticationSuccessHandler介面。
[html] view plain copy
- <sec:form-login login-page="/login.jsp"
- login-processing-url="/login.do"
- authentication-failure-url="/login.jsp"
- authentication-success-handler-ref="authenticationSuccessHandler"
- />
然後在前臺登入頁面中改下form中的action就可以了。
配置檔案,注意這裡的defaultTargetUrl,本來這個是在form-login中,配置的但是如果我們自己定義登入成功後的處理程式後它就不起作用了,所以這個跳轉也需要我們在自定義程式中處理。
- <bean id="authenticationSuccessHandler" class="com.zrhis.system.security.SimpleLoginSuccessHandler">
- <property name="defaultTargetUrl" value="/WEB-INF/app.jsp"></property>
- <property name="forwardToDestination" value="true"></property>
- </bean>
- package com.zrhis.system.security;
- 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.InitializingBean;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.dao.DataAccessException;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.web.DefaultRedirectStrategy;
- import org.springframework.security.web.RedirectStrategy;
- import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
- import org.springframework.transaction.annotation.Propagation;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.StringUtils;
- import com.zrhis.base.exception.InitializationException;
- import com.zrhis.system.bean.SysUsers;
- import com.zrhis.system.repository.SysUsersRepository;
- public class SimpleLoginSuccessHandler implements AuthenticationSuccessHandler,InitializingBean {
- protected Log logger = LogFactory.getLog(getClass());
- private String defaultTargetUrl;
- private boolean forwardToDestination = false;
- private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
- @Autowired
- private SysUsersRepository sysUsersRepository;
- /* (non-Javadoc)
- * @see org.springframework.security.web.authentication.AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
- */
- @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);
- if(this.forwardToDestination){
- logger.info("Login success,Forwarding to "+this.defaultTargetUrl);
- request.getRequestDispatcher(this.defaultTargetUrl).forward(request, response);
- }else{
- logger.info("Login success,Redirecting to "+this.defaultTargetUrl);
- this.redirectStrategy.sendRedirect(request, response, this.defaultTargetUrl);
- }
- }
- @Transactional(readOnly=false,propagation= Propagation.REQUIRED,rollbackFor={Exception.class})
- public void saveLoginInfo(HttpServletRequest request,Authentication authentication){
- SysUsers user = (SysUsers)authentication.getPrincipal();
- try {
- String ip = this.getIpAddress(request);
- Date date = new Date();
- user.setLastLogin(date);
- user.setLoginIp(ip);
- this.sysUsersRepository.saveAndFlush(user);
- } catch (DataAccessException e) {
- if(logger.isWarnEnabled()){
- logger.info("無法更新使用者登入資訊至資料庫");
- }
- }
- }
- public String getIpAddress(HttpServletRequest request){
- String ip = request.getHeader("x-forwarded-for");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("WL-Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("HTTP_CLIENT_IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("HTTP_X_FORWARDED_FOR");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getRemoteAddr();
- }
- return ip;
- }
- public void setDefaultTargetUrl(String defaultTargetUrl) {
- this.defaultTargetUrl = defaultTargetUrl;
- }
- public void setForwardToDestination(boolean forwardToDestination) {
- this.forwardToDestination = forwardToDestination;
- }
- /* (non-Javadoc)
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
- */
- @Override
- public void afterPropertiesSet() throws Exception {
- if(StringUtils.isEmpty(defaultTargetUrl))
- throw new InitializationException("You must configure defaultTargetUrl");
- }
- }
實現InitializingBean,在afterPropertiesSet中我們驗證defaultTargetUrl是否為空,如果為空就丟擲異常,因為這個地址是必須的。可以根據自己的情況來選擇要不要加驗證。
如果實現InitializingBean在程式啟動是Spring在建立完這個類並注入屬性後會自動執行afterPropertiesSet,所以我們的一些初始化的操作也是可以在這裡完成的。
onAuthenticationSuccess是主要的介面這個是登入成功後Spring呼叫的方法,而我們的跳轉和儲存使用者資訊都是在這裡完成的。
RedirectStrategy是Spring提供的一個客戶端跳轉的工具類。使用它可以支援“/index.jsp”這種地址,同時可以保證伺服器跳轉和客戶端跳轉的路徑一致。
加入我們的專案名為my ,專案訪問地址為http://localhost:8080/my
現在要使用客戶端跳轉到 "/login.jsp" 如果是response.sendRedirect 會直接跳轉到http://localhost:8080/login.jsp
而使用redirectStrategy.sendRedirect則會跳轉到http://localhost:8080/my/login.jsp
在redirectStrategy中,'/'代表的是專案根目錄而不是伺服器根目錄。