栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【security】spring security放行不生效,security放行后还是被拦截,路径变成了/error

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【security】spring security放行不生效,security放行后还是被拦截,路径变成了/error

文章目录
  • security最初的配置
  • 初步改进后的配置
  • 排查真实原因
  • 更加合理的配置

之前写了篇关于security认证的文章 感觉对security了解多了一点,直到遇到过滤器层面的问题,才明白security终究还是那个复杂的security。

security最初的配置
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 登录成功处理类
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");

        http.authorizeRequests()
                //静态文件允许访问
                .antMatchers().permitAll()
                // 放行
                .antMatchers( "/assets
    @Override
    public void configure(WebSecurity web) throws Exception {
          // 直接放行了  如果是login接口 必须通过HttpSecurity 走过滤链 因为登录涉及 SecurityContextHolder
        web.ignoring().antMatchers("/test)就是说我们没有传httpMethod
 		//  httpMethod 为null 不走该判断
        if (this.httpMethod != null && StringUtils.hasText(request.getMethod()) && this.httpMethod != valueOf(request.getMethod())) {
            if (logger.isDebugEnabled()) {
                logger.debug("Request '" + request.getMethod() + " " + this.getRequestPath(request) + "' doesn't match '" + this.httpMethod + " " + this.pattern + "'");
            }

            return false;
            // 如果antMatchers(
        // 可以看到除了 "GET", "HEAD", "TRACE", "OPTIONS" 四种方式 其它请求都会被拦截
        if (!this.requireCsrfProtectionMatcher.matches(request)) {
            filterChain.doFilter(request, response);
        } else {
        	// 其它请求 没有token会被拦截
            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));
                }

            } else {
                filterChain.doFilter(request, response);
            }
        }
    }

这就是为什么我们get请求可以访问 而put,delete等请求失败的原因。

更加合理的配置
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 登录成功处理类
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");

        http.authorizeRequests()
                //静态文件允许访问
                .antMatchers().permitAll()
                // 放行
                .antMatchers( "/assets/**","/login","/test/**","/testfather/**","/testes/**","/advice/**","css/**","/js/**","/image/*").permitAll()
                //其他所有请求需要登录, anyRequest 不能配置在 antMatchers 前面
                .anyRequest().authenticated()
                .and()
                //登录页面配置,用于替换security默认页面
                .formLogin().loginPage(  "/login").successHandler(successHandler).and()
                //登出页面配置,用于替换security默认页面
                .logout().logoutUrl( "/logout").and()
                .httpBasic().and()
                // 开启了csrf防御 如果要放行/test/** 还需要在下面ignoringAntMatchers进行配置
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                // 这里还需要放行 当然如果是 .csrf().disable()就不会有这个问题了
                .ignoringAntMatchers(
                        "/instances",
                        "/actuator/**",
                        "/test/**",
                        "/advice/**",
                        "/testes/**"
                );

    }
}

为什么有的项目没有ignoringAntMatchers配置也放行成功了呢? 因为那些项目 很可能直接.csrf().disable() 所以不会出现该问题

题外话: 想必可能有同学听过 controller层接口必须捕获异常 ,如果不捕获 其中坑点之一就和这个security框架的.csrf()有关:

 * 异常没有捕获 ==》
 * 如果当开启了 csrf 且又没有放行时 (在 WebSecurity 放行了 否则进不来接口) 异常会抛到 security  导致security报错(同样需要debug级别日志查看  error看不到) 且返回401
 * 换句话说:WebSecurity放行的方式 还需配合接口的try catch 否则接口报错了 也会返回401
 * 当然 其它情况可能也会因为异常没捕获 而造成未知结果 
 * 所以我们还是应该遵循规范:接口必须异常捕获
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/880952.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号