背景:
我要做的系統前面放置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
