spring security 6:放行某些请求-接口

spring boot 3.1.10

spring-boot-starter-security 3.1.10

spring security web 6.1.8

--

ben发布于博客园

序章

自定义了 Bean SecurityFilterChain,在 http.authorizeHttpRequests 中放行了 接口“/system/register”,还定义了 session管理 的 invalidSessionStrategy。

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/system/register").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(sm -> sm
.invalidSessionStrategy(new AppInvalidSessionStrategy())
)

)

return http.build();

}

可是,遇到了问题:访问 /system/register 时,提示 “无效凭证”——由 invalidSessionStrategy 触发

无效凭证的原因 是 请求自带了 Cookie JSESSIONID,触发了 SESSION 验证机制,验证无效,由 自定义的  invalidSessionStrategy 处理——返回错误信息。

期望:接口 /system/register 无需验证、授权即可访问。

 

解决方案1:添加Bean WebSecurityCustomizer

根据 参考资料#1 的介绍,添加了一个 Bean WebSecurityCustomizer,解决了问题。

@Bean
public WebSecurityCustomizer ignoringCustomizer() {
    // 忽略注册接口
    return (web) -> web.ignoring()
        .requestMatchers("/system/register");
}

更多介绍,请查看 参考资料#1。

ben发布于博客园

解决方案2:添加 空Filter列表 的 Bean SecurityFilterChain(推荐)

根据 官网文档:

Spring Security > Servlet Applications > Architecture(https://docs.spring.io/spring-security/reference/servlet/architecture.html) 的介绍,

可以 添加多个 SecurityFilterChain 实例(multiple SecurityFilterChain instances),各个实例 处理 不同的请求

官方图官方图-multi-securityfilterchain.png

在官文 中有这样一句话:

It is important to note that each SecurityFilterChain can be unique and can be configured in isolation.

In fact, a SecurityFilterChain might have zero security Filter instances if the application wants Spring Security to ignore certain requests.

翻译(金山词霸):

需要注意的是,每个安全过滤器链都可以是 唯一的,并且可以 进行 隔离配置。

实际上,如果应用程序 希望Spring安全程序 忽略 某些请求,那么 安全过滤器链 可能 没有任何安全过滤器实例

这不正是自己想要的吗——忽略某些请求(/system/register)?

鼓捣了好一会儿,最终,直接 添加一个 空Filter列表 的 Bean SecurityFilterChain 从而实现了需求。

@Bean
public SecurityFilterChain securityFilterChainEmpty() {

    return new SecurityFilterChain() {
        private RequestMatcher requestMatcher = request -> request
            .getRequestURI().startsWith("/system/register");
        @Override
        public boolean matches(HttpServletRequest request) {
            return requestMatcher.matches(request);
        }

        @Override
        public List<Filter> getFilters() {
            return new ArrayList<>();
        }
    };
}

ben发布于博客园

小结

推荐使用 解决方案#2。

没事多看看 官方文档。

 

---END---

ben发布于博客园

本文链接:

https://www.cnblogs.com/luo630/p/18125429

ben发布于博客园

参考资料

1、SpringSecurity6解决requestMatchers().permitAll()后依然执行自定义过滤器的问题

吃青椒的秋草鹦鹉
已于 2023-06-04 22:02:31 修改
https://blog.csdn.net/m0_54250110/article/details/131037578

2、

 

ben发布于博客园

ben发布于博客园

 

posted @ 2024-04-10 11:14  快乐的总统95  阅读(645)  评论(0编辑  收藏  举报