zoukankan      html  css  js  c++  java
  • Springsecurity源码Filter之LogoutFilter(十三)

    负责处理登出相关逻辑,默认url映射是/logout

    org.springframework.security.config.annotation.web.configurers.LogoutConfigurer 初始化

    默认初始化处https://www.cnblogs.com/LQBlog/p/15508248.html#autoid-12-0-0

    private void applyDefaultConfiguration(HttpSecurity http) throws Exception {
            //http本质也是build 这里都是配置默认的config configure add CsrfConfigurer
            http.csrf();
            //默认增加一个WebAsyncManagerIntegrationFilter
            http.addFilter(new WebAsyncManagerIntegrationFilter());
            //configures add ExceptionHandlingConfigurer
            http.exceptionHandling();
            //configures add HeadersConfigurer
            http.headers();
            //configures add SessionManagementConfigurer
            http.sessionManagement();
            //configure add SecurityContextConfigurer
            http.securityContext();
            //configure add RequestCacheConfigurer
            http.requestCache();
            ///configure add AnonymousConfigurer
            http.anonymous();
            ///configure add ServletApiConfigurer
            http.servletApi();
            //configure DefaultLoginPageConfigurer
            http.apply(new DefaultLoginPageConfigurer<>());
            //configure LogoutConfigurer
            http.logout();
        }

    通过http.logout().addLogoutHandler() 可以自定义handler

    LogoutFilter

        private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            //匹配是否能够处理 默认是/logout
            if (requiresLogout(request, response)) {
                //从SecurityContextHolder 获得Authentication信息
                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug(LogMessage.format("Logging out [%s]", auth));
                }
                /**
                 * 调用CompositeLogoutHandler 他也实现了LogoutHandler 他只是一个统一的管理器
                 * 内部循环调用LogoutHandler
                 * 默认有三种
                 * PersistentTokenBasedRememberMeServices <1>
                 * SecurityContextLogoutHandler <2>
                 * LogoutSuccessEventPublishingLogoutHandler<3>
                 */
                this.handler.logout(request, response, auth);
                //处理登出成功的SimpleUrlLogoutSuccessHandler 比如重定向到登录页
                this.logoutSuccessHandler.onLogoutSuccess(request, response, auth);
                return;
            }
            chain.doFilter(request, response);
        }

    <1>

    org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices#logout

        @Override
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            //清除cookile
            super.logout(request, response, authentication);
            if (authentication != null) {
                //删除token
                this.tokenRepository.removeUserTokens(authentication.getName());
            }
        }

    <2>

    org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler#logout

     @Override
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            Assert.notNull(request, "HttpServletRequest required");
            if (this.invalidateHttpSession) {
                HttpSession session = request.getSession(false);
                if (session != null) {
                    //清空session
                    session.invalidate();
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug(LogMessage.format("Invalidated session %s", session.getId()));
                    }
                }
            }
            if (this.clearAuthentication) {
                //清空
                SecurityContext context = SecurityContextHolder.getContext();
                context.setAuthentication(null);
            }
            //清空
            SecurityContextHolder.clearContext();
        }

    <3>

    发布一个spring的事件我们可以监听这个事件 知道某个用户登出了 参考:https://www.cnblogs.com/LQBlog/p/13878553.html#_label5

    org.springframework.security.web.authentication.logout.LogoutSuccessEventPublishingLogoutHandler#logout

    @Override
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            if (this.eventPublisher == null) {
                return;
            }
            if (authentication == null) {
                return;
            }
            this.eventPublisher.publishEvent(new LogoutSuccessEvent(authentication));
        }
  • 相关阅读:
    (转)Javascript如何正确使用getElementById,getElementsByName() and getElementsByTagName()
    把一个json字符串转换成对应的c#类型
    (转)C#数字转固定长度的字符串
    WDBuyNET.DMSFrame.DMSLinq内部方法
    (Transfered)DOM最常用的方法和属性(Javascript DOM编程艺术,DOM Scripting)
    三星颁布发表供应多款Android手机全新晋级
    APNIC执委赵巍:IPv4向IPv6过渡再无退路
    谷歌Android操纵市廛下架染辣手机软件
    盗窟手机小我私人撤军华强北:市场一年不如一年
    华为“黑室”命系商务部防线
  • 原文地址:https://www.cnblogs.com/LQBlog/p/15533703.html
Copyright © 2011-2022 走看看