統一認證 - Apereo CAS 客戶端的整合以及小結
前兩篇介紹了Apereo CAS以及伺服器端的安裝,但還不夠完整,服務端還沒有Application真正用起來呢!這篇文章將介紹怎麼用起來
整合的目的
客戶端我們想要與Apereo CAS做什麼整合呢?回顧一下Apereo CAS是做什麼的?Apereo CAS的一個功能就是單點登入,統一的登入登出介面與頁面,讓系統中的模組只需要關注在業務點,而把安全認證的功能交給統一認證來做。所以客戶端的整合主要是單點登入的整合,客戶端指定需要做安全認證的頁面,然後Apereo CAS的安全包檢測校驗使用者登入情況,並自動與CAS登入頁面進行跳轉互動。
客戶端的配置
Apereo CAS提供了Springboot的包,可以讓我們的整合些微方便了那麼一丟丟!首先我們建立一個Springboot的application,裡面帶了Apereo CAS start的依賴
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-cas</artifactId> </dependency>
同時在application.properties檔案裡面指定啟動的埠server.port = 9000
有了Apereo CAS的包之後,我們就可以進行程式碼的配置。客戶端的配置按照SpringSecurity的安全檢驗流程進行的:
- 使用者嘗試開啟一個受保護的url,比如/admin/user
-
AuthenticationEntryPoint
被觸發了,把使用者重定向到配置好的CAS登入頁面https://localhost :6443/cas - 使用者輸入使用者名稱密碼,登入成功後, CAS會跳轉回application指定的回撥urlhttp://localhost :9000/login/cas, 並帶上ticket作為查詢引數
-
CasAuthenticationFilter
一直在監聽/login/cas
這個路徑,當發現有請求後,它會觸發CasTicketValidator,由CasTickerValidator檢驗ticket的有效性 - 當ticket也驗證成功後,使用者將會被跳轉回原來請求的受保護url
下面程式碼大致描述了這個過程:
@Bean public ServiceProperties serviceProperties() { ServiceProperties serviceProperties = new ServiceProperties(); serviceProperties.setService("http://localhost:9000/login/cas"); serviceProperties.setSendRenew(false); return serviceProperties; } @Bean @Primary public AuthenticationEntryPoint authenticationEntryPoint( ServiceProperties sP) { CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint(); entryPoint.setLoginUrl("https://localhost:6443/cas/login"); entryPoint.setServiceProperties(sP); return entryPoint; } @Bean public TicketValidator ticketValidator() { return new Cas30ServiceTicketValidator( "https://localhost:6443/cas"); } @Bean public CasAuthenticationProvider casAuthenticationProvider() { CasAuthenticationProvider provider = new CasAuthenticationProvider(); provider.setServiceProperties(serviceProperties()); provider.setTicketValidator(ticketValidator()); provider.setUserDetailsService( s -> new User("casuser", "Mellon", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_ADMIN"))); provider.setKey("CAS_PROVIDER_LOCALHOST_9000"); return provider; }
@EnableWebSecurity @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { private AuthenticationProvider authenticationProvider; private AuthenticationEntryPoint authenticationEntryPoint; private SingleSignOutFilter singleSignOutFilter; private LogoutFilter logoutFilter; @Autowired public SecurityConfig(CasAuthenticationProvider casAuthenticationProvider, AuthenticationEntryPoint eP, LogoutFilter lF , SingleSignOutFilter ssF ) { this.authenticationProvider = casAuthenticationProvider; this.authenticationEntryPoint = eP; this.logoutFilter = lF; this.singleSignOutFilter = ssF; } // ... @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authenticationProvider); } @Override protected AuthenticationManager authenticationManager() throws Exception { return new ProviderManager(Arrays.asList(authenticationProvider)); } @Bean public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sP) throws Exception { CasAuthenticationFilter filter = new CasAuthenticationFilter(); filter.setServiceProperties(sP); filter.setAuthenticationManager(authenticationManager()); return filter; } }
下面這個檔案配置了application中所有/secured/*
,login
的URL都是受保護資源,都要經過CAS認證過才可以訪問:
@EnableWebSecurity @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .regexMatchers("/secured.*", "/login") .authenticated() .and() .authorizeRequests() .regexMatchers("/") .permitAll() .and() .httpBasic() .authenticationEntryPoint(authenticationEntryPoint); } // ... }
服務端Apereo CAS的配置
跟所有統一認證平臺一樣,所有application想要跟CAS做整合的,都需要在CAS配置相應的引數才可以使用。Apereo CAS提供了很多配置的方式,有YML,JSON, MongoDB以及其他(可查官網)。但高度自由的CAS一如既往的,沒有提供視覺化操作的介面。比如我們採用JSON的方式。首先我們需要通知Apereo CAS我們採用的是JSON的方式,並通知JSON檔案的路徑在哪裡
cas.serviceRegistry.initFromJson=true cas.serviceRegistry.config.location=classpath:/services
然後我們在這個目錄裡面,建立一個對應的JSON檔案,儲存我們的客戶端資訊,為了方面管理,建議檔名為 application_id.json, 比如"secureApp_9991.json", 內容如下:
{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^http://localhost:9000/login/cas", "name" : "CAS Spring Secured App", "description": "This is a Spring App that usses the CAS Server for it's authentication", "id" : 19991, "evaluationOrder" : 1 }
第一次配置從JSON載入客戶端配置的話,需要重啟Apereo CAS。之後再加新的客戶端的話就不用再重啟,Apereo CAS會自動監測這個資料夾的變動
小結
至此我們對於Apereo CAS就有了一個稍微完整一點點的瞭解,從服務端安裝部署,到配置,以及客戶端如何整合等。但從這個短時間的學習來看,如果企業已經重度使用了Apereo CAS,那相信它可以很好地服務支撐企業的應用。但如果是新的專案,特別是專案週期比較緊張的專案,並且團隊之前沒有對統一認證有技術積累的話,不是很建議採用Apereo CAS,這些細微的配置以及無所不在的隱藏功能,會讓你給專案經理催死的! 後面我會介紹另外一個統一認證的框架,個人感覺能彌補Apereo CAS的短板的