@[TOC](spring security 整合sso全記錄)
# 介紹一下我司的sso流程
我司的sso流程:
1。 app在sso系統註冊想被sso攔截的sso url, 本app註冊了app/index
2。 sso會在公司閘道器層攔截 app/index的url,根據使用者cookie是否攜帶正確token,決定是否觸發登入流程(如果已經登入,則直接放行到(app/index),如果沒有登入,則轉發到全司統一的sso登入頁面)
3。 sso驗證通過後,會重定向到app(app/index),app可以拿到使用者登入資訊
# app security 整合sso的思路
1。 app對使用者提交的請求路徑,利用spring security 判斷使用者是否登入,如未登入,則重定向到app/index, sso會在閘道器層抓到這個url,從而觸發sso登入流程。
2。 登入成功後,app拿到登入資訊(userid等),設定認證透過,獲取user在本app的角色等資訊,並儲存到security。
3。 登入成功後的使用者,再次訪問app時,app就可以利用spring security判斷使用者是否登入了。
## 要解決的問題
1。 可以看出,本案例中其實不需要spring security預設提供的登入頁面,我們要讓security知道我們想要跳轉的登入url是app/index(POST方法)
2。 sso登入成功後,會跳轉回到我們的app url(app/index,GET方法)。怎麼讓security知道,並啟動spring security的認證流程?
3。 重寫security的驗證方法attemptAuthentication, 我們認為透過sso登入成功後,就預設登入app是驗證透過的。
4。 由於app是採用的前臺loadbalance+後臺機器叢集的方式。前臺的loadballance方式,由於我司流程,不能設定sticky session。 所以需採用springsession(redis)的方式
# 上程式碼
1。 解決第一個問題,很簡單,在spring-security。xml裡面配置
2。 第二個問題的解決稍微複雜一點:
我們要重寫驗證流程,是顯而易見的。於是,新建cMToolAuthenticationFilter extends UsernamePasswordAuthenticationFilter
xml配置如下
在CMToolAuthenticationFilter裡面,增加initCMAuFilter方法,指定觸發security驗證流程的url:/app/index
public class CMToolAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @PostConstruct public void initCMAuFilter(){ //這裡指定觸發security驗證流程的url:/app/index RequestMatcher requiresAuthenticationRequestMatcher = new AntPathRequestMatcher(“/app/index”, “GET”); this。setRequiresAuthenticationRequestMatcher(requiresAuthenticationRequestMatcher); //這裡可以順便指定一下,登入成功後的自定義handler=>CMToolSuccessHandler this。setAuthenticationSuccessHandler(new CMToolSuccessHandler(“/cmtv1web/home”,userAuthenticateService)); }@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { //寫你自己的登入驗證邏輯 。。。。。 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, “”); setDetails(request, authRequest); return super。getAuthenticationManager()。authenticate(authRequest); } //指定authenticationManager @Override public void setAuthenticationManager(AuthenticationManager authenticationManager) { super。setAuthenticationManager(authenticationManager); }
```
CMToolAuthenticationProvider
```
@Autowired UserAuthenticateService userAuthenticateService; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication。getName(); List
```
spring session redis的整合, 有時間再寫吧!