美文网首页
Spring Cloud Gateway 与Spring Sec

Spring Cloud Gateway 与Spring Sec

作者: erika002 | 来源:发表于2023-04-17 23:05 被阅读0次

目前系统使用的网关是Spring Cloud Gateway,并且加入了Spring Security来保护系统。 用户认证是基于jwt来认证,因此没用使用session。

但是经过测试发现,当请求的cookie中有session时,服务端响应的set-cookie 中也有session字段,并且session是空值,因此我们需要禁用session,避免返回空值。

1.如果是基于springmvc的服务,那么禁用session 可以在配置类WebSecurityConfigurerAdapter的子类中增加session相关的配置

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //设置session为无状态模式 
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.antMatchers("/**").permitAll();
    }

2.但是Spring Cloud Gateway 是基于spring webflux 没有上面的WebSecurityConfigurerAdapter配置类,经过翻看代码发现,在默认的ServerWebExchange的实现类DefaultServerWebExchange中有关于session的配置

DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
            WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
            LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) {

        Assert.notNull(request, "'request' is required");
        Assert.notNull(response, "'response' is required");
        Assert.notNull(sessionManager, "'sessionManager' is required");
        Assert.notNull(codecConfigurer, "'codecConfigurer' is required");
        Assert.notNull(localeContextResolver, "'localeContextResolver' is required");

        // Initialize before first call to getLogPrefix()
        this.attributes.put(ServerWebExchange.LOG_ID_ATTRIBUTE, request.getId());

        this.request = request;
        this.response = response;
        //session 管理 默认的为DefaultWebSessionManager 使用的是InMemoryWebSessionStore
        this.sessionMono = sessionManager.getSession(this).cache();
        this.localeContextResolver = localeContextResolver;
        this.formDataMono = initFormData(request, codecConfigurer, getLogPrefix());
        this.multipartDataMono = initMultipartData(request, codecConfigurer, getLogPrefix());
        this.applicationContext = applicationContext;
    }

基于此可以在系统中 注入一个WebSessionManager,此WebSessionManager初始化为DefaultWebSessionManager,并且调用setSessionIdResolver方法。
设置的SessionIdResolver为CookieWebSessionIdResolver的子类,置空session过期的方法expireSession
此时相当于session过期之后不做任何处理,因此也不会有set-cookie的响应
,如下

    @Bean
    public WebSessionManager webSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        defaultWebSessionManager.setSessionIdResolver(new CookieWebSessionIdResolver(){
            @Override
            public void expireSession(ServerWebExchange exchange) {
                //session 过期不做任何处理
            }
        });

        return defaultWebSessionManager;
    }

此时DefaultServerWebExchange中的sessionManager 就被替换成我们自定义的返回空的session的对象。此时不对session做任何处理。最终返回出去的set-cookie 中就没有session 相关的内容。

相关文章

网友评论

      本文标题:Spring Cloud Gateway 与Spring Sec

      本文链接:https://www.haomeiwen.com/subject/mtxhjdtx.html