spring session 和 spring security整合

时间:2023-01-11 03:39:46

背景:

我要做的系统前面放置zuul。 使用自己公司提供的单点登录服务。后面的业务应用也是spring boot支撑的rest服务。

目标:

使用spring security管理权限包括权限。用户请求过来之后。自动单点登录,zuul以及后面的所有应用共享session(含权限和登录)信息。

计划:

工作分为zuul部分和rest部分

在zuu这边,我们需要

    • 实现和配置filter,调用已有的单点登录服务,实现用户身份校验,权限获得。并且存入session中
    • 配置spring session。确保session被持久化。在我选的方案里是redis

在rest这边

    • 配置spring session。可以从redis中读取session
    • 实现Filter,未登录的返回错误

zuul和rest应用都启用spring session。 从zuul打到rest上的请求自动识别为已登录的,从session中获得权限信息。业务基于权限控制。

spring默认的filter是这些。其中springSecurityFilterChain比较特殊是安全相关的一堆filter

name=metricsFilter, filterClass=org.springframework.boot.actuate.autoconfigure.MetricsFilter
name=characterEncodingFilter, filterClass=org.springframework.boot.web.filter.OrderedCharacterEncodingFilter
name=springSessionRepositoryFilter, filterClass=org.springframework.session.web.http.SessionRepositoryFilter
name=hiddenHttpMethodFilter, filterClass=org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter
name=httpPutFormContentFilter, filterClass=org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter
name=requestContextFilter, filterClass=org.springframework.boot.web.filter.OrderedRequestContextFilter
name=springSecurityFilterChain, filterClass=org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean$1
name=webRequestLoggingFilter, filterClass=org.springframework.boot.actuate.trace.WebRequestTraceFilter
name=shallowEtagHeaderFilter, filterClass=com.gome.sso.common.filter.UserCookieCheckFilter
name=applicationContextIdFilter, filterClass=org.springframework.boot.web.filter.ApplicationContextHeaderFilter
name=Tomcat WebSocket (JSR356) Filter, filterClass=org.apache.tomcat.websocket.server.WsFilter

启用web security之后默认的一套filter是这样的。我们可以自己开发一个来替换掉BasicAuthenticationFilter

0 = {WebAsyncManagerIntegrationFilter@13209}
1 = {SecurityContextPersistenceFilter@13210}
2 = {HeaderWriterFilter@13211}
3 = {LogoutFilter@13212}
4 = {BasicAuthenticationFilter@13213}
5 = {RequestCacheAwareFilter@13214}
6 = {SecurityContextHolderAwareRequestFilter@13215}
7 = {AnonymousAuthenticationFilter@13216}
8 = {SessionManagementFilter@13217}
9 = {ExceptionTranslationFilter@13218}
10 = {FilterSecurityInterceptor@13219}

替换的代码如下。继承WebSecurityConfigurerAdapter并覆盖com.gome.cs.online.WebSecurityConfig#configure方法

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    .....

    @Override
protected void configure(HttpSecurity http) throws Exception {
CustomSsoFilter ssoFilter = new CustomSsoFilter();
ssoFilter.setLoginUrl(loginUrl);
http.addFilterAfter(ssoFilter, LogoutFilter.class);
}
}

这个配置下除了没有了,连FilterSecurityInterceptor也没有了,

zuul的默认设置在转发时会删除掉这些headerCookie,Set-Cookie,Authorization。 对于我们信任的rest当然就不需要了

要进行如下设置

zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders: Cookie,Set-Cookie,Authorization
serviceId: myuser-rest

好了,这样我们就实现了在zuul和其背后的应用间共享session