springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析

这篇具有很好参考价值的文章主要介绍了springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景描述

最近在写一个前端端分离的微服务项目,使用到了网关zuul,然后网关的权限控制是通过springsecurity来实现的,真是踩了很多坑。

问题描述

项目配置

  1. 因为要进行登录认证,就放行了一部分url无需认证权限控制。
  2. 然后其他的所有url都需要进行认证权限控制。
  3. 配置代码如下:
@Configuration
public class SecurityGateway extends WebSecurityConfigurerAdapter {
   
// 指定要忽略的路径
private static final String[] IGNORE_PATH = {
            "/maple_gateway/", "/maple_gateway/index", "/maple_gateway/login", "/maple_gateway/error.html",
            "/maple_gateway/api/user_api/user_common/v1/auth/get_verify_code",
            "/maple_gateway/api/user_api/user_common/v1/auth/check_verify_core"
    };


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        		// 配置忽略url
                .antMatchers(IGNORE_PATH).permitAll()
                // 其他所有请求都需要认证
                .anyRequest().authenticated()

}

抛出异常

  1. InsufficientAuthenticationException,这个异常是说权限不足,没有足够的权限访问资源。
org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource
  1. 但其实这个不是真的的异常,真正的异常是 org.springframework.security.access.AccessDeniedException: Access is denied
    下面来进入到分析过程:

异常分析

由于springsecurity的异常处理和mvc的异常处理不一样,认证类异常和权限异常并不能被全局异常捕获,而是他内部自己处理的。

反向追踪链路

在发生异常时,会进入到ExceptionTranslationFilter (异常转换过滤器),将发生的异常转换为认证或者权限异常。
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
可以看到,在处理异常是,最初的异常是AccessDeniedException,然后将它转换为了InsufficientAuthenticationException异常。

然后在向上追踪,定位发生异常的过滤器。过滤器链在执行某一个过滤器方法是,发生了异常。
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析

思路分析

现在已经明确是在执行某一个过滤器的方法是发生异常了,由于确实对springsecurity不太熟悉,导致debug的时候走了很多弯路。

  1. 首先,我已经将本次请求的url添加到忽略名单里了,其实这些过滤器是不会执行的。所有最开始我的debug思路错了。问题的本质是我的忽略url没有生效,而不是过滤器产生异常。
  2. 所有正确的做法应该是先去定位过滤器忽略指定url的逻辑在那里,然后去看是什么问题。
  3. 还要说明的一点是,正常来说,指定了正确忽略的url,内置的一些过滤器不会走,但是你自定义的,实现了OncePerRequestFilter的过滤器还是会走的,所有需要自己去过滤。

好了,下面先来说我的错误debug思路

错误Debug
  1. 我认为是发生异常的原因是我的权限问题,所有我定位到了发生异常的起点,如下图所属:

springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
只要当访问策略投票机制返回-1,则会抛出异常。继续往下
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
到达三元表达式,这里也就是前面的表达式返回false就会抛出异常。继续:
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
这里最关键的就是框中的代码,其实这里已经将结果求出来了,为false,会抛出异常,下面那个只是去做类型转换的,现在我们要搞清楚的是为什么会出现false。继续,:
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
中间稍微省去了一部分,但是这里是关键,这个方法名已经很见名知意了,读取属性值,现在的属性是authenticated,就是读取他的属性,意思是否已经认证,返回true表示已经认证,也就是上面方面的返回值也就是true,也就不会抛出异常了;但是现在显然不是true,我们继续来看这个属性是怎么拿到的
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
可以看到,这里已经求出来是否认证了,false,未认证;这里其实就是用反射去调用了一个方法,isAuthenticated,是否通过身份验证,继续,为什么会返回false。
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
结果很清晰,是否认证过的依据是是否是匿名访问,我这里是忽略url,就是要在登录之前访问,所以肯定就是匿名的访问,所以返回了true,是否认证返回了false,然后投票返回了-1,然后跑出来异常。

正确Debug
  1. 之所以说上面的分析是错误的,是因为这里并没有忽略url的逻辑判断,并不是我想要的东西,所以其实问题不是出在这里,而是在更前面。
  2. 不知道有没有有没有人注意到上面的分析过程,其实就是取属性authenticated的值,表示是不是已经认证过了,那这不是很奇怪吗,我配置了过滤指定url,还是走了过滤器,需要判断认证。
  3. 其实根本不需要,一开始去获取authenticated属性的值就是错的。

重新查看投票方法org.springframework.security.access.vote.AffirmativeBased.decide
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
可以看到,configAttributes这里list里面存放的就是我们要求的属性值,仔细去看,有一个key是authenticated,也就是我们要求查用户是否认证,但是不对啊,我请求的url配置了忽略认证的,怎么他的匹配模式是anyRrequest,这明显和我的配置不对啊。现在可以知道,是这个配置出了问题,我们去看这个list是怎么来的:
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
向上一层,可以发现是这里获取到的配置,继续:
‘’
‘’
‘’
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
现在是不是很清晰了,这个map是不是很熟悉,这就是我们开始配置的过滤url,然后这里就是当前请求嫩能不能和配置的忽略请求匹配的上,如果能配置上,就获取他对应的value。但是很奇怪的时,我当前请求居然和配置的对不上。

springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
不能说完全一样吧,也就是基本相同,这居然匹配不上,去看看他的matches方法怎么实现的。
‘’
‘’
‘’springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
水落石出了,我靠,他里面居然是用的getRequestPath,获取到的uri是没有context前缀的,因为我这个项目是微服务的,所有我加了网关加了前缀,结果没有匹配上。

解决

  1. 配置的忽略url去掉网关前缀。
    springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析
    现在可以看到,获取到的属性就正确了,不会在去验证权限。也就不会抛出权限不足的异常。

然后在说明一点,自己定义的过滤器还是会走,比如我这里的AuthFilter,当前的url也是忽略url,但是也还是走了过滤器,也能是我的方法不对,知道的可以告诉我。
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析文章来源地址https://www.toymoban.com/news/detail-433490.html

总结

  1. springsecurity认证忽略的url是不能包含context前缀的,否则匹配不上。
  2. 自定义的放行策略逻辑在org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource#getAttributes.
  3. 实现OncePerRequestFilter的自定义过滤器不会忽略配置的url,还是会执行过滤器。
  4. 针对于【3】的解决方案:SpringSecurity 配置permitAll之后仍然会走自定义过滤器Filter的问题

到了这里,关于springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • idea如何debug看springsecurity的过滤器顺序

    先配置一个Spring启动对象,后续需要根据这个对象来获取SpringSecurity的过滤器链 设置一个输出信息,需要在输出信息这里打上断点,才方便查看过滤器链 debug启动后,走到输出这里 点击调试框的计算器图标,或按 Alt + F8 输入 applicationContext.getBean(FilterChainProxy.class) ,点击Evaluat

    2024年04月15日
    浏览(34)
  • [CSCCTF 2019 Qual]FlaskLight 过滤 url_for globals 绕过globals过滤

    目录 subprocess.Popen FILE warnings.catch_warnings site._Printer 这题很明显就是 SSTI了 源代码 我们试试看 {{7*7}} 然后我们就开始吧 原本我的想法是直接{{url_for.__globals__}} 但是回显是直接500 猜测过滤 我们正常来吧 这里我们需要 os 来调用 但是这里存在一个类 可以不需要os Python3 subprocess

    2024年02月07日
    浏览(38)
  • nginx拦截指定的url

    在配置nginx规则拦截的时候我们要清楚自己的需求 需求如下: 外网地址: 不能被访问 内网地址: 能访问 外网地址如下:外网ip+端口/pac/pul/check     (这里域名ip都可以) 内网地址如下:内网ip+端口/pac/pul/check               (内网ip不做拦截) nginx配置如下: 上面的配置和

    2024年01月23日
    浏览(34)
  • 腾达(Tenda)FH451路由器通过设置URL过滤限制网页访问

    适用路由器型号:F450/F451/F453/Ff455/F456/FH450/FH451 通过设置URL过滤来限制连接到该路由器下打开的网页,通过进入到路由器管理界面中(在地址栏中输入默认IP地址:192.168.0.1),在安全设置-URL过滤,中进行设置。 登陆管理界面 你需要登录到路由器管理界面来进行设置,此时,

    2024年02月06日
    浏览(59)
  • js跳转到指定url

    js怎么跳转到指定url方法如下: 需求:页面上点击按钮 需要调用设备提供的地址

    2024年02月11日
    浏览(50)
  • @FeignClient指定多个url实现负载均衡

    C知道回答的如下: 在使用 FeignClient 调用多个 URL 实现负载均衡时,可以使用 Spring Cloud Ribbon 提供的功能来实现。下面是一个示例代码:  首先,在Spring Boot主类上添加@EnableFeignClients注解启用Feign Client功能。 然后,在Spring Boot 项目的 Maven 配置文件中,添加以下依赖: 接下来

    2024年02月14日
    浏览(29)
  • 自定义TypeFilter 指定@ComponentScan注解的过滤规则

    在使用@ComponentScan注解实现包扫描时,可以使用@Filter指定过滤规则,在@Filter中,通过type来指定过滤的类型。而@Filter注解中的type属性是一个FilterType枚举,其源码如下。 例如,使用@ComponentScan注解进行包扫描时,如果要想按照注解只包含标注了@Controller注解的组件,那么就需要

    2023年04月24日
    浏览(38)
  • SpringBoot缓存注解@Cacheable之自定义key策略及缓存失效时间指定

    1. 项目依赖 本项目借助 SpringBoot 2.2.1.RELEASE  +  maven 3.5.3  +  IDEA  +  redis5.0 进行开发 开一个 web 服务用于测试 1. key 生成策略 对于 @Cacheable 注解,有两个参数用于组装缓存的 key cacheNames/value: 类似于缓存前缀 key: SpEL 表达式,通常根据传参来生成最终的缓存 key 默认的 redisK

    2024年02月19日
    浏览(39)
  • Linux :: 内容过滤指令【3】:grep 指令【详解】:在指定文件中过滤搜索信息、(模糊)查找包含指定字符串的内容!(如:系统故障时,查看操作日志信息等情景)

    前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit。 学习集: C++ 入门到入土!!!学习合集 Linux 从命令到网络再到内核!学习合集 注:find 指令常与 grep 指令在面试中被提及,需让你回答异同! 目录索引: 1. 基本语法、功能及使

    2024年02月09日
    浏览(57)
  • C语言跳转浏览器打开指定URL

    该代码使用 sprintf() 函数将要打开的URL添加到一个系统命令中,然后使用 system() 函数调用该命令以默认浏览器打开URL。请注意,该命令在Windows和Linux系统中略有不同,所以在编写时需要注意平台差异性。 下面是适用于windwos平台的 该代码使用 ShellExecute() 函数打开默认浏览器,

    2023年04月26日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包