Spring Security 核心过滤器链讲解

目录
  • 一、Filter Chain 图解
  • 二、过滤器逐一解析
    • 2.1.WebAsyncManagerIntegrationFilter
    • 2.2.SecurityContextPersistenceFilter
    • 2.3.HeaderWriterFilter
    • 2.4.CsrfFilter
    • 2.5.LogoutFilter
    • 2.6.RequestCacheAwareFilter
    • 2.7.SecurityContextHolderAwareRequestFilter
    • 2.8.AnonymousAuthenticationFilter
    • 2.9.SessionManagementFilter
    • 2.10.ExceptionTranslationFilter
    • 2.11.FilterSecurityInterceptor
    • 2.12.UsernamePasswordAuthenticationFilter

前言:

在熟悉Spring Security的使用和基本操作后,有时根据项目需求,我们需要在security原有的过滤器链中,添加符合我们自己的过滤器来实现功能时,我们就必须得先了解security的核心过滤链的流程和每个过滤器的各自功能,以此,我们才可以在特点的过滤器前后加入属于我们项目需求的过滤器。

一、Filter Chain 图解

在配置了spring security了之后,会在运行项目的时候,DefaultSecurityFilterChain会输出相关log:

    public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters){
        logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
        this.requestMatcher = requestMatcher;
        this.filters = new ArrayList<Filter>(filters);
    }

输出以下Log:

[main] o.s.s.web.DefaultSecurityFilterChain     :
Creating filter chain:
org.springframework.security.web.util.matcher.AnyRequestMatcher@1,
[
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@184de357,
    org.springframework.security.web.context.SecurityContextPersistenceFilter@521ba38f,
    org.springframework.security.web.header.HeaderWriterFilter@77bb916f,
    org.springframework.security.web.csrf.CsrfFilter@76b305e1,
    org.springframework.security.web.authentication.logout.LogoutFilter@17c53dfb,
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2086d469,
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@b1d19ff,
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter@efe49ab,
    org.springframework.security.web.session.SessionManagementFilter@5a48d186,
    org.springframework.security.web.access.ExceptionTranslationFilter@273aaab7
]

也可以从Debug进行查看:

二、过滤器逐一解析

在解析前,先说说两个至关重要的类:OncePerRequestFilter和GenericFilterBean,在过滤器链的过滤器中,或多或少间接或直接继承到

  • OncePerRequestFilter顾名思义,能够确保在一次请求只通过一次filter,而不需要重复执行。
  • GenericFilterBean是javax.servlet.Filter接口的一个基本的实现类
  • GenericFilterBean将web.xml中filter标签中的配置参数-init-param项作为bean的属性
  • GenericFilterBean可以简单地成为任何类型的filter的父类
  • GenericFilterBean的子类可以自定义一些自己需要的属性
  • GenericFilterBean,将实际的过滤工作留给他的子类来完成,这就导致了他的子类不得不实现doFilter方法
  • GenericFilterBean不依赖于Spring的ApplicationContext,Filters通常不会直接读取他们的容器信息(ApplicationContext concept)而是通过访问spring容器(Spring root application context)中的service beans来获取,通常是通过调用filter里面的getServletContext() 方法来获取

2.1.WebAsyncManagerIntegrationFilter

  public final class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter {
        ......
    @Override
    protected void doFilterInternal(HttpServletRequest request,
        HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
      WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
      SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor) asyncManager
          .getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
      if (securityProcessingInterceptor == null) {
        asyncManager.registerCallableInterceptor(CALLABLE_INTERCEPTOR_KEY,
            new SecurityContextCallableProcessingInterceptor());
      }
      filterChain.doFilter(request, response);
    }
  }

从源码中,我们可以分析出WebAsyncManagerIntegrationFilter相关功能:

  • 根据请求封装获取WebAsyncManager
  • 从WebAsyncManager获取/注册SecurityContextCallableProcessingInterceptor

2.2.SecurityContextPersistenceFilter

    public class SecurityContextPersistenceFilter extends GenericFilterBean {
        ......
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            if (request.getAttribute(FILTER_APPLIED) != null) {
                // ensure that filter is only applied once per request
                chain.doFilter(request, response);
                return;
            }
            final boolean debug = logger.isDebugEnabled();
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
            if (forceEagerSessionCreation) {
                HttpSession session = request.getSession();
                if (debug && session.isNew()) {
                    logger.debug("Eagerly created session: " + session.getId());
                }
            }
            HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
                    response);
            SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
            try {
                SecurityContextHolder.setContext(contextBeforeChainExecution);
                chain.doFilter(holder.getRequest(), holder.getResponse());
            }
            finally {
                SecurityContext contextAfterChainExecution = SecurityContextHolder
                        .getContext();
                // Crucial removal of SecurityContextHolder contents - do this before anything
                // else.
                SecurityContextHolder.clearContext();
                repo.saveContext(contextAfterChainExecution, holder.getRequest(),
                        holder.getResponse());
                request.removeAttribute(FILTER_APPLIED);
                if (debug) {
                    logger.debug("SecurityContextHolder now cleared, as request processing completed");
                }
            }
        }
            ......
    }

从源码中,我们可以分析出SecurityContextPersistenceFilter相关功能:

  • 先实例SecurityContextHolder->HttpSessionSecurityContextRepository(下面以repo代替).作用:其会从Session中取出已认证用户的信息,提高效率,避免每一次请求都要查询用户认证信息。
  • 根据请求和响应构建HttpRequestResponseHolder
  • repo根据HttpRequestResponseHolder加载context获取SecurityContext
  • SecurityContextHolder将获得到的SecurityContext设置到Context中,然后继续向下执行其他过滤器
  • finally-> SecurityContextHolder获取SecurityContext,然后清除,并将其和请求信息保存到repo,从请求中移除FILTER_APPLIED属性

2.3.HeaderWriterFilter

public class HeaderWriterFilter extends OncePerRequestFilter {
    ......
    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        for (HeaderWriter headerWriter : headerWriters) {
            headerWriter.writeHeaders(request, response);
        }
        filterChain.doFilter(request, response);
    }
}

从源码中,我们可以分析HeaderWriterFilter相关功能:

  • 往该请求的Header中添加相应的信息,在http标签内部使用security:headers来控制

2.4.CsrfFilter

public final class CsrfFilter extends OncePerRequestFilter {
    ......
    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
        request.setAttribute(HttpServletResponse.class.getName(), response);
        CsrfToken csrfToken = this.tokenRepository.loadToken(request);
        final boolean missingToken = csrfToken == null;
        if (missingToken) {
            csrfToken = this.tokenRepository.generateToken(request);
            this.tokenRepository.saveToken(csrfToken, request, response);
        }
        request.setAttribute(CsrfToken.class.getName(), csrfToken);
        request.setAttribute(csrfToken.getParameterName(), csrfToken);
        if (!this.requireCsrfProtectionMatcher.matches(request)) {
            filterChain.doFilter(request, response);
            return;
        }
        String actualToken = request.getHeader(csrfToken.getHeaderName());
        if (actualToken == null) {
            actualToken = request.getParameter(csrfToken.getParameterName());
        }
        if (!csrfToken.getToken().equals(actualToken)) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Invalid CSRF token found for "
                        + UrlUtils.buildFullRequestUrl(request));
            }
            if (missingToken) {
                this.accessDeniedHandler.handle(request, response,
                        new MissingCsrfTokenException(actualToken));
            }
            else {
                this.accessDeniedHandler.handle(request, response,
                        new InvalidCsrfTokenException(csrfToken, actualToken));
            }
            return;
        }
        filterChain.doFilter(request, response);
    }
        ......
}

从源码中,我们可以分析出CsrfFilter相关功能:

  • csrf又称跨域请求伪造,攻击方通过伪造用户请求访问受信任站点。
  • 对需要验证的请求验证是否包含csrf的token信息,如果不包含,则报错。这样攻击网站无法获取到token信息,则跨域提交的信息都无法通过过滤器的校验。

2.5.LogoutFilter

public class LogoutFilter extends GenericFilterBean {
    ......
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (requiresLogout(request, response)) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (logger.isDebugEnabled()) {
                logger.debug("Logging out user '" + auth
                        + "' and transferring to logout destination");
            }
            this.handler.logout(request, response, auth);
            logoutSuccessHandler.onLogoutSuccess(request, response, auth);
            return;
        }
        chain.doFilter(request, response);
    }
    ......
}

从源码中,我们可以分析出LogoutFilter相关功能:

  • 匹配URL,默认为/logout
  • 匹配成功后则用户退出,清除认证信息

2.6.RequestCacheAwareFilter

public class RequestCacheAwareFilter extends GenericFilterBean {
  ......
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest wrappedSavedRequest = requestCache.getMatchingRequest(
                (HttpServletRequest) request, (HttpServletResponse) response);
        chain.doFilter(wrappedSavedRequest == null ? request : wrappedSavedRequest,
                response);
    }
}

从源码中,我们可以分析出RequestCacheAwareFilter相关功能:

通过HttpSessionRequestCache内部维护了一个RequestCache,用于缓存HttpServletRequest

2.7.SecurityContextHolderAwareRequestFilter

public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
  ......
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            chain.doFilter(this.requestFactory.create((HttpServletRequest) req,
                    (HttpServletResponse) res), res);
    }
    ......
}

从源码中,我们可以分析出SecurityContextHolderAwareRequestFilter相关功能:

  • 针对ServletRequest进行了一次包装,使得request具有更加丰富的API

2.8.AnonymousAuthenticationFilter

public class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean {
        ......
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            if (SecurityContextHolder.getContext().getAuthentication() == null) {
                SecurityContextHolder.getContext().setAuthentication(
                        createAuthentication((HttpServletRequest) req));
                if (logger.isDebugEnabled()) {
                    logger.debug("Populated SecurityContextHolder with anonymous token: '"
                            + SecurityContextHolder.getContext().getAuthentication() + "'");
                }
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '"
                            + SecurityContextHolder.getContext().getAuthentication() + "'");
                }
            }
            chain.doFilter(req, res);
    }
    ......
}

从源码中,我们可以分析出AnonymousAuthenticationFilter相关功能:

  • 当SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder中。匿名身份过滤器,这个过滤器个人认为很重要,需要将它与UsernamePasswordAuthenticationFilter 放在一起比较理解,spring security为了兼容未登录的访问,也走了一套认证流程,只不过是一个匿名的身份。
  • 匿名认证过滤器,可能有人会想:匿名了还有身份?个人对于Anonymous匿名身份的理解是Spirng Security为了整体逻辑的统一性,即使是未通过认证的用户,也给予了一个匿名身份。而AnonymousAuthenticationFilter该过滤器的位置也是非常的科学的,它位于常用的身份认证过滤器(如UsernamePasswordAuthenticationFilter、BasicAuthenticationFilter、RememberMeAuthenticationFilter)之后,意味着只有在上述身份过滤器执行完毕后,SecurityContext依旧没有用户信息,AnonymousAuthenticationFilter该过滤器才会有意义—-基于用户一个匿名身份。

2.9.SessionManagementFilter

public class SessionManagementFilter extends GenericFilterBean {
        ......
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            if (request.getAttribute(FILTER_APPLIED) != null) {
                chain.doFilter(request, response);
                return;
            }
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
            if (!securityContextRepository.containsContext(request)) {
                Authentication authentication = SecurityContextHolder.getContext()
                        .getAuthentication();
                if (authentication != null && !trustResolver.isAnonymous(authentication)) {
                    // The user has been authenticated during the current request, so call the
                    // session strategy
                    try {
                        sessionAuthenticationStrategy.onAuthentication(authentication,
                                request, response);
                    }
                    catch (SessionAuthenticationException e) {
                        // The session strategy can reject the authentication
                        logger.debug(
                                "SessionAuthenticationStrategy rejected the authentication object",
                                e);
                        SecurityContextHolder.clearContext();
                        failureHandler.onAuthenticationFailure(request, response, e);
                        return;
                    }
                    // Eagerly save the security context to make it available for any possible
                    // re-entrant
                    // requests which may occur before the current request completes.
                    // SEC-1396.
                    securityContextRepository.saveContext(SecurityContextHolder.getContext(),
                            request, response);
                }
                else {
                    // No security context or authentication present. Check for a session
                    // timeout
                    if (request.getRequestedSessionId() != null
                            && !request.isRequestedSessionIdValid()) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Requested session ID "
                                    + request.getRequestedSessionId() + " is invalid.");
                        }
                        if (invalidSessionStrategy != null) {
                            invalidSessionStrategy
                                    .onInvalidSessionDetected(request, response);
                            return;
                        }
                    }
                }
            }
        chain.doFilter(request, response);
    }
    ......
}

从源码中,我们可以分析出SessionManagementFilter相关功能:

  • securityContextRepository限制同一用户开启多个会话的数量
  • SessionAuthenticationStrategy防止session-fixation protection attack(保护非匿名用户)

2.10.ExceptionTranslationFilter

public class ExceptionTranslationFilter extends GenericFilterBean {
    ......
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        try {
            chain.doFilter(request, response);
            logger.debug("Chain processed normally");
        }
        catch (IOException ex) {
            throw ex;
        }
        catch (Exception ex) {
            // Try to extract a SpringSecurityException from the stacktrace
            Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex);
            RuntimeException ase = (AuthenticationException) throwableAnalyzer
                    .getFirstThrowableOfType(AuthenticationException.class, causeChain);
            if (ase == null) {
                ase = (AccessDeniedException) throwableAnalyzer.getFirstThrowableOfType(
                        AccessDeniedException.class, causeChain);
            }
            if (ase != null) {
                handleSpringSecurityException(request, response, chain, ase);
            }
            else {
                // Rethrow ServletExceptions and RuntimeExceptions as-is
                if (ex instanceof ServletException) {
                    throw (ServletException) ex;
                }
                else if (ex instanceof RuntimeException) {
                    throw (RuntimeException) ex;
                }
                // Wrap other Exceptions. This shouldn't actually happen
                // as we've already covered all the possibilities for doFilter
                throw new RuntimeException(ex);
            }
        }
    }
    ......
}

从源码中,我们可以分析出ExceptionTranslationFilter相关功能:

  • ExceptionTranslationFilter异常转换过滤器位于整个springSecurityFilterChain的后方,用来转换整个链路中出现的异常
  • 此过滤器的作用是处理中FilterSecurityInterceptor抛出的异常,然后将请求重定向到对应页面,或返回对应的响应错误代码

2.11.FilterSecurityInterceptor

public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
        ......
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }
    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return this.securityMetadataSource;
    }
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }
    public void invoke(FilterInvocation fi) throws IOException, ServletException {
            if ((fi.getRequest() != null)
                    && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
                    && observeOncePerRequest) {
                // filter already applied to this request and user wants us to observe
                // once-per-request handling, so don't re-do security checking
                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
            }
            else {
                // first time this request being called, so perform security checking
                if (fi.getRequest() != null) {
                    fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
                }
                InterceptorStatusToken token = super.beforeInvocation(fi);
                try {
                    fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
                }
                finally {
                    super.finallyInvocation(token);
                }
                super.afterInvocation(token, null);
            }
    }
    ......
}

从源码中,我们可以分析出FilterSecurityInterceptor相关功能:

  • 获取到所配置资源访问的授权信息
  • 根据SecurityContextHolder中存储的用户信息来决定其是否有权限
  • 主要一些实现功能在其父类AbstractSecurityInterceptor中

2.12.UsernamePasswordAuthenticationFilter

public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
        ......
        public Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException {
            if (postOnly && !request.getMethod().equals("POST")) {
                throw new AuthenticationServiceException(
                        "Authentication method not supported: " + request.getMethod());
            }
            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);
            // Allow subclasses to set the "details" property
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
    }
    ......
}

从源码中,我们可以分析出UsernamePasswordAuthenticationFilter相关功能:

  • 表单认证是最常用的一个认证方式,一个最直观的业务场景便是允许用户在表单中输入用户名和密码进行登录,而这背后的UsernamePasswordAuthenticationFilter,在整个Spring Security的认证体系中则扮演着至关重要的角色

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Security之默认的过滤器链及自定义Filter操作

    Spring Security 过滤器链及自定义Filter 别名 类名称 Namespace Element or Attribute CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channel SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http CONCURRENT_SESSION_FILTER ConcurrentSessionF

  • 全面解析Spring Security 过滤器链的机制和特性

    1. 前言 过滤器作为 Spring Security 的重中之重,我们需要了解其中的机制.这样我们才能根据业务需求的变化进行定制.今天来探讨一下 Spring Security 中的过滤器链机制. 2. Spring Security 过滤器链 客户端(APP 和后台管理客户端)向应用程序发送请求,然后应用根据请求的 URI 的路径来确定该请求的过滤器链(Filter)以及最终的具体 Servlet 控制器(Controller). 从上图我们可以看出 Spring Security 以一个单

  • Spring Security常用过滤器实例解析

    Spring Security常见的15个拦截器 1 . org.springframework.security.web.context.SecurityContextPersistenceFilter 首当其冲的一个过滤器,作用之重要,自不必多言. SecurityContextPersistenceFilter主要是使用SecurityContextRepository在session中保存或更新一个 SecurityContext,并将SecurityContext给以后的过滤器使用,来

  • Spring Security 核心过滤器链讲解

    目录 一.Filter Chain 图解 二.过滤器逐一解析 2.1.WebAsyncManagerIntegrationFilter 2.2.SecurityContextPersistenceFilter 2.3.HeaderWriterFilter 2.4.CsrfFilter 2.5.LogoutFilter 2.6.RequestCacheAwareFilter 2.7.SecurityContextHolderAwareRequestFilter 2.8.AnonymousAuthe

  • Spring Security的过滤器链机制

    目录 前言 请求执行链路 推荐阅读 前言 在“码农小胖哥”的文章中提到一个关键的过滤器链SecurityFilterChain,当一个请求 HttpServletRequest 进入 SecurityFilterChain 时,会通过 matches 方法来确定是否满足条件进入过滤器链,进而决定请求应该执行哪些过滤器.下面我们自己来梳理一遍. 请求执行链路 我们以之前的文章为例,使用@Configuration配置了一个SecurityFilterChain Bean,能在Spring Boot

  • Spring Security基于过滤器实现图形验证码功能

    目录 前言 一. 验证码简介 二. 基于过滤器实现图形验证码 1. 实现概述 2. 创建新模块 3. 添加依赖包 4. 创建Producer对象 5. 创建生成验证码的接口 6. 自定义异常 7. 创建拦截验证码的过滤器 8. 编写SecurityConfig 9. 编写测试页面 10. 代码结构 11. 启动项目测试 前言 在前两个章节中,一一哥 带大家学习了Spring Security内部关于认证授权的核心API,以及认证授权的执行流程和底层原理.掌握了这些之后,对于Spring Secu

  • 详解最简单易懂的Spring Security 身份认证流程讲解

    最简单易懂的Spring Security 身份认证流程讲解 导言 相信大伙对Spring Security这个框架又爱又恨,爱它的强大,恨它的繁琐,其实这是一个误区,Spring Security确实非常繁琐,繁琐到让人生厌.讨厌也木有办法呀,作为JavaEE的工程师们还是要面对的,在开始之前,先打一下比方(比方好可怜): Spring Security 就像一个行政服务中心,如果我们去里面办事,可以办啥事呢?可以小到咨询简单问题.查询社保信息,也可以户籍登记.补办身份证,同样也可以大到企业事

  • Spring security 自定义过滤器实现Json参数传递并兼容表单参数(实例代码)

    依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g

  • Spring Security 多过滤链的使用详解

    目录 一.背景 二.需求 1.给客户端使用的api 2.给网站使用的api 三.实现方案 方案一: 方案二 四.实现 1.app 端 Spring Security 的配置 五.实现效果 1.app 有权限访问 api 2.app 无权限访问 api 3.admin 用户有权限访问 网站 api 4.dev 用户无权限访问 网站 api 六.完整代码 一.背景 在我们实际的开发过程中,有些时候可能存在这么一些情况,某些api 比如: /api/** 这些是给App端使用的,数据的返回都是以JSO

  • Spring Security CsrfFilter过滤器用法实例

    这篇文章主要介绍了Spring Security CsrfFilter过滤器用法实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 spring security框架提供的默认登录页面,会有一个name属性值为_csrf的隐藏域: 这是框架在用户访问登录页面之前就生成的,保存在内存中,当用户提交表单的时候会跟着一起提交:_csrf_formdata 然后会经过spring security框架resources目录下配置文件spring-sec

  • Java中的Spring Security配置过滤器

    目录 AbstractAuthenticationFilterConfigurer 改造过程 配置类效果 前言: CaptchaAuthenticationFilter是通过模仿UsernamePasswordAuthenticationFilter实现的.同样的道理,由于UsernamePasswordAuthenticationFilter的配置是由FormLoginConfigurer来完成的,应该也能模仿一下FormLoginConfigurer,写一个配置类CaptchaAuthent

  • Spring Security过滤器链加载执行流程源码解析

    目录 Spring Security实现原理 一.Spring Security过滤器链加载 1.注册名为 springSecurityFilterChain的过滤器 2.查看 DelegatingFilterProxy类 3.查看 FilterChainProxy类 3.1 查看 doFilterInternal方法. 3.2 查看 getFilters方法. 4 查看 SecurityFilterChain接口 5 查看 SpringBootWebSecurityConfiguration类

随机推荐