spring security 单一账户多地方登陆提醒, ajax 拦截器 Interceptor

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring security 单一账户多地方登陆提醒, ajax 拦截器 Interceptor相关的知识,希望对你有一定的参考价值。

spring-security.xml部分代码:

    <http auto-config="false" >
        <access-denied-handler ref="accessDeniedHandler" />
        <!-- 
        <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/" always-use-default-target="true" />
        -->
        <http-basic />
        <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
        <custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER" />
        <!-- 替换默认的LogoutFilter <logout logout-success-url="/login.jsp" /> -->
        <custom-filter ref="ylLogoutFilter" before="LOGOUT_FILTER" />
        <custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
        <custom-filter ref="carParkLogoutFilter" after="LOGOUT_FILTER" />
        <!-- 增加一个自定义的customSecurityInterceptor,放在FILTER_SECURITY_INTERCEPTOR之前, 实现用户、角色、权限、资源的数据库管理。 --> 
        <custom-filter ref="customSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
        <remember-me />
        <!-- 会话管理配置  -->
        <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy" invalid-session-url="/logon/commonSessionExpired.htm"/>
    </http>
    <beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">  
        <beans:property name="sessionRegistry" ref="sessionRegistry" />  
        <beans:property name="expiredUrl" value="/logon/commonSessionExpired.htm" />  
    </beans:bean>

拦截过期:spring-mvc.xml 这里主要是为了弹窗口,不弹窗口就不用做下面了

    <mvc:interceptors>
        <!-- 特定路径下才拦截 -->
        <mvc:interceptor>
            <mvc:mapping path="/logon/commonSessionExpired.htm"/>
            <bean class="com.jevon.frame.security.SessionInterceptor"/> 
        </mvc:interceptor> 
    </mvc:interceptors>

拦截器:SessionInterceptor, 这里需要区分ajax请求,和普通请求,ajax返回需要转换成JSON格式的,这里ReturnResult使用Map代替就可以了

package com.jevon.frame.security;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.jevon.can.common.domain.ReturnResult;
import net.sf.json.JSONObject;

public class SessionInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            /**
            String url = request.getServletPath();
            if (url != null && url.contains("/logon/expiredUrl")) {
                return Boolean.TRUE;
            }**/
            if (null == request.getSession().getAttribute("SES_CURRENTUSER")) {
                if(isAjax(request)){
                    PrintWriter out = response.getWriter();
                    JSONObject jsonObject = JSONObject.fromObject(new ReturnResult("页面过期,请重新登录!", "logout", false));
                    out.print(jsonObject);
                    out.close();
                }else{
                    PrintWriter out = response.getWriter();
                    StringBuilder builder = new StringBuilder();
                    builder.append("<script type=\\"text/javascript\\" charset=\\"UTF-8\\">");
                    builder.append("window.top.logoutAlert(\\"页面过期,请重新登录!\\");");//alert(\\"页面过期,请重新登录!\\");");
                    builder.append("</script>");
                    out.print(builder.toString());
                    out.close();
                }
                return false;
            } 
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
        super.afterCompletion(request, response, handler, ex);
    }
    
    //判断是否ajax请求
    public static boolean isAjax(HttpServletRequest request) {  
         return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));  
    }  
}

封装的ajax.js返回:这里使用的是logout类型

        loadComplete: function (data) {
            if (data.success === false) {
                if (data.msgType == ‘1‘) {
                    window.parent.location = $.getProjectName() + ‘/logon/commonQuit.htm‘;
                }
                if (data.msgType == ‘2‘ && data.msg) {
                    $.messager.alert("警告", data.msg, "warning");
                }
                if (data.msgType == ‘3‘ && data.msg) {
                    $.messager.alert("错误", data.msg, "error");
                }
                if(data.msgType == ‘logout‘) {
                    $.messager.alert("警告", data.msg, "info", function(r) {
                        window.parent.location = $.getProjectName() + ‘/logon/expiredUrl.htm‘;
                    });
                }
            }
        }

最顶层jsp页面:拦截器直接调用该方法,alert 就可以使用到样式

<script>
     function logoutAlert(msg) {
        $.messager.alert("警告", msg, "info", function(r) {
             window.location = $.getProjectName() + ‘/logon/expiredUrl.htm‘;
        });
    }
</script>

 

技术分享

 

以上是关于spring security 单一账户多地方登陆提醒, ajax 拦截器 Interceptor的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 使用非spring默认的登陆页面,是如何跳转到登陆成功页面的?

spring security 登陆报错java.lang.StackOverflowError: null?

Spring Security---多次登录失败账户锁定详解

Spring Security 预认证账户锁定检查

Spring boot Security 登陆安全配置

spring boot security angular6 自定义登录的登录页面怎么配置?有没有大神指点一下?