自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringSecurity系列之SpringBoot+CAS單點(diǎn)登錄

開發(fā) 架構(gòu)
某一個(gè) Client 需要接入 CAS Server 進(jìn)行驗(yàn)證,則該 Client 必須提前在 CAS Server 上配置其信息。這個(gè)信息既可以動(dòng)態(tài)添加,也可以通過 JSON 來配置,后面松哥會教搭建如何動(dòng)態(tài)添加,這里方便起見,我們還是通過 JSON 來進(jìn)行配置。

 [[408875]]

1.準(zhǔn)備工作

準(zhǔn)備工作主要做兩件事。

1.1 服務(wù)記錄

某一個(gè) Client 需要接入 CAS Server 進(jìn)行驗(yàn)證,則該 Client 必須提前在 CAS Server 上配置其信息。

這個(gè)信息既可以動(dòng)態(tài)添加,也可以通過 JSON 來配置,后面松哥會教搭建如何動(dòng)態(tài)添加,這里方便起見,我們還是通過 JSON 來進(jìn)行配置。

具體配置方式如下,在 CAS Server 中創(chuàng)建如下目錄:

  1. src/main/resources/services 

在該目錄下創(chuàng)建一個(gè)名為 client1-99.json 的文件,client1 表示要接入的 client 的名字,99 表示要接入的 client 的 id,json 文件內(nèi)容如下(這個(gè)配置可以參考官方給出的模版:overlays/org.apereo.cas.cas-server-webapp-tomcat-5.3.14/WEB-INF/classes/services/Apereo-10000002.json):

  1.   "@class""org.apereo.cas.services.RegexRegisteredService"
  2.   "serviceId""^(https|http)://.*"
  3.   "name""client1"
  4.   "id": 99, 
  5.   "description""應(yīng)用1 的定義信息"
  6.   "evaluationOrder": 1 

這段 JSON 配置含義如下:

  1. @calss 指定注冊服務(wù)類,這個(gè)是固定的org.apereo.cas.services.RegexRegisteredService。
  2. serviceId 則通過正則表達(dá)式用來匹配具體的請求。
  3. name 是接入的 client 的名稱。
  4. id 是接入的 client 的 id。
  5. description 是接入的 client 的描述信息。
  6. evaluationOrder 則指定了執(zhí)行的優(yōu)先級。

接下來再在 src/main/resources/application.properties 文件中配置剛剛 json 的信息,如下:

  1. cas.serviceRegistry.json.location=classpath:/services 
  2. cas.serviceRegistry.initFromJson=true 

這里有兩行配置:

  1. 指定配置 JSON 文件的位置。
  2. 開啟 JSON 識別。

OK,配置完成后,重啟 CAS Server。

CAS Server 啟動(dòng)成功后,我們在控制臺看到如下日志,表示 JSON 配置已經(jīng)加載成功了:

1.2 JDK 證書

第二個(gè)要提前準(zhǔn)備的東西就是 JDK 證書。

在實(shí)際開發(fā)中,這一步可以忽略,但是因?yàn)槲覀儸F(xiàn)在用的自己生成的 SSL 證書,所以我們要將自己生成的證書導(dǎo)入到 JDK 中,否則在使用 Spring Security 接入 CAS 單點(diǎn)登錄時(shí),會拋出如下錯(cuò)誤:

[[408877]]

將 SSL 證書導(dǎo)入 JDK 中的命令其實(shí)也很簡單,兩個(gè)步驟,第一個(gè)導(dǎo)出 .cer 文件,第二步,導(dǎo)入 JDK,命令如下:

  1. keytool -export -trustcacerts -alias casserver -file ./cas.cer -keystore ./keystore 
  2. sudo keytool -import -trustcacerts -alias casserver -file ./cas.cer -keystore /Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home/lib/security/cacerts 

注意,在執(zhí)行 export 導(dǎo)出命令時(shí),需要輸入密鑰口令,這個(gè)口令就是自己一開始創(chuàng)建 SSL 證書時(shí)設(shè)置的。在執(zhí)行 import 導(dǎo)入命令時(shí),也需要輸入口令,這個(gè)口令是 changeit,注意,不是自己一開始設(shè)置的。

密鑰庫的位置在 JDK 目錄下的 /lib/security/cacerts,小伙伴們根據(jù)自己實(shí)際情況來修改(在 JDK9 之前,位置在 jre/lib/security/cacerts)。

我們在本地測試一定要導(dǎo)入證書到 JDK 證書庫中,否則后面的測試會出現(xiàn)上圖中的錯(cuò)誤,證書導(dǎo)入 JDK 證書庫之后,要確保之后的開發(fā)中,使用的是本地的 JDK。

注意,JDK 證書導(dǎo)入之后,CASServer 需要重啟一下。

1.3 修改 hosts

另外,我們還需要修改電腦 hosts 文件,因?yàn)榍懊骊P(guān)于 CAS Server,關(guān)于 SSL 證書的配置都涉及到域名,所以后面的訪問我們將通過域名的形式訪問,hosts 文件中添加如下兩條記錄:

第一個(gè)是 CAS Server 的請求域名,第二個(gè)是 CAS Client 的請求域名。

2.開發(fā) Client

在使用 Spring Security 開發(fā) CAS Client 之前,有一個(gè)基本問題需要先和小伙伴們捋清楚:用戶登錄是在 CAS Server 上登錄,所以 Spring Security 中雖然依舊存在用戶的概念,但是對于用戶的處理邏輯會和前面的有所不同。

好了,接下來我們來看下具體步驟。

首先我們來創(chuàng)建一個(gè)普通的 Spring Boot 項(xiàng)目,加入 Web 依賴 和 Spring Security 依賴,如下:

項(xiàng)目創(chuàng)建成功后,我們再來手動(dòng)加入 cas 依賴:

  1. <dependency> 
  2.     <groupId>org.springframework.security</groupId> 
  3.     <artifactId>spring-security-cas</artifactId> 
  4. </dependency> 

 

接下來,在 application.properties 中配置 CAS Server 和 CAS Client 的請求地址信息:

  1. cas.server.prefix=https://cas.javaboy.org:8443/cas 
  2. cas.server.login=${cas.server.prefix}/login 
  3. cas.server.logout=${cas.server.prefix}/logout 
  4.  
  5. cas.client.prefix=http://client1.cas.javaboy.org:8080 
  6. cas.client.login=${cas.client.prefix}/login/cas 
  7. cas.client.logoutRelative=/logout/cas 
  8. cas.client.logout=${cas.client.prefix}${cas.client.logoutRelative} 

這些配置都是自定義配置,所以配置的 key 可以自己隨意定義。至于配置的含義都好理解,分別配置了 CAS Server 和 CAS Client 的登錄和注銷地址。

配置好之后,我們需要將這些配置注入到實(shí)體類中使用,這里就用到了類型安全的屬性綁定。

這里我創(chuàng)建兩個(gè)類分別用來接收 CAS Server 和 CAS Client 的配置文件:

  1. @ConfigurationProperties(prefix = "cas.server"
  2. public class CASServerProperties { 
  3.     private String prefix; 
  4.     private String login; 
  5.     private String logout; 
  6.     //省略 getter/setter 
  7. @ConfigurationProperties(prefix = "cas.client"
  8. public class CASClientProperties { 
  9.     private String prefix; 
  10.     private String login; 
  11.     private String logoutRelative; 
  12.     private String logout; 
  13.     //省略 getter/setter 

另外記得在啟動(dòng)類上面添加 @ConfigurationPropertiesScan 注解來掃描這兩個(gè)配置類:

  1. @SpringBootApplication 
  2. @ConfigurationPropertiesScan 
  3. public class Client1Application { 
  4.  
  5.     public static void main(String[] args) { 
  6.         SpringApplication.run(Client1Application.class, args); 
  7.     } 

這里配置完成后,我們一會將在配置文件中來使用。

接下來創(chuàng)建 CAS 的配置文件,略長:

  1. @Configuration 
  2. public class CasSecurityConfig { 
  3.     @Autowired 
  4.     CASClientProperties casClientProperties; 
  5.     @Autowired 
  6.     CASServerProperties casServerProperties; 
  7.     @Autowired 
  8.     UserDetailsService userDetailService; 
  9.  
  10.     @Bean 
  11.     ServiceProperties serviceProperties() { 
  12.         ServiceProperties serviceProperties = new ServiceProperties(); 
  13.         serviceProperties.setService(casClientProperties.getLogin()); 
  14.         return serviceProperties; 
  15.     } 
  16.  
  17.     @Bean 
  18.     @Primary 
  19.     AuthenticationEntryPoint authenticationEntryPoint() { 
  20.         CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint(); 
  21.         entryPoint.setLoginUrl(casServerProperties.getLogin()); 
  22.         entryPoint.setServiceProperties(serviceProperties()); 
  23.         return entryPoint; 
  24.     } 
  25.  
  26.     @Bean 
  27.     TicketValidator ticketValidator() { 
  28.         return new Cas20ProxyTicketValidator(casServerProperties.getPrefix()); 
  29.     } 
  30.  
  31.     @Bean 
  32.     CasAuthenticationProvider casAuthenticationProvider() { 
  33.         CasAuthenticationProvider provider = new CasAuthenticationProvider(); 
  34.         provider.setServiceProperties(serviceProperties()); 
  35.         provider.setTicketValidator(ticketValidator()); 
  36.         provider.setUserDetailsService(userDetailService); 
  37.         provider.setKey("javaboy"); 
  38.         return provider; 
  39.     } 
  40.  
  41.     @Bean 
  42.     CasAuthenticationFilter casAuthenticationFilter(AuthenticationProvider authenticationProvider) { 
  43.         CasAuthenticationFilter filter = new CasAuthenticationFilter(); 
  44.         filter.setServiceProperties(serviceProperties()); 
  45.         filter.setAuthenticationManager(new ProviderManager(authenticationProvider)); 
  46.         return filter; 
  47.     } 
  48.  
  49.     @Bean 
  50.     SingleSignOutFilter singleSignOutFilter() { 
  51.         SingleSignOutFilter sign = new SingleSignOutFilter(); 
  52.         sign.setIgnoreInitConfiguration(true); 
  53.         return sign; 
  54.     } 
  55.     @Bean 
  56.     LogoutFilter logoutFilter() { 
  57.         LogoutFilter filter = new LogoutFilter(casServerProperties.getLogout(), new SecurityContextLogoutHandler()); 
  58.         filter.setFilterProcessesUrl(casClientProperties.getLogoutRelative()); 
  59.         return filter; 
  60.     } 

這個(gè)配置文件略長,但是并不難,我來和大家挨個(gè)解釋:

  1. 首先一進(jìn)來注入三個(gè)對象,這三個(gè)中,有兩個(gè)是我們前面寫的配置類的實(shí)例,另外一個(gè)則是 UserDetailsService,關(guān)于 UserDetailsService,我想我也不必多做解釋,大家參考本系列前面的文章就知道 UserDetailsService 的作用,一會我會給出 UserDetailsService 的實(shí)現(xiàn)。
  2. 接下來配置 ServiceProperties,ServiceProperties 中主要配置一下 Client 的登錄地址即可,這個(gè)地址就是在 CAS Server 上登錄成功后,重定向的地址。
  3. CasAuthenticationEntryPoint 則是 CAS 驗(yàn)證的入口,這里首先設(shè)置 CAS Server 的登錄地址,同時(shí)將前面的 ServiceProperties 設(shè)置進(jìn)去,這樣當(dāng)它登錄成功后,就知道往哪里跳轉(zhuǎn)了。
  4. TicketValidator 這是配置 ticket 校驗(yàn)地址,CAS Client 拿到 ticket 要去 CAS Server 上校驗(yàn),默認(rèn)校驗(yàn)地址是:https://cas.javaboy.org:8443/cas/proxyValidate?ticket=xxx
  5. CasAuthenticationProvider 主要用來處理 CAS 驗(yàn)證邏輯,關(guān)于 AuthenticationProvider 松哥在前面的文章中和大家分享過(SpringSecurity 自定義認(rèn)證邏輯的兩種方式(高級玩法)),當(dāng)時(shí)就說,想要自定義認(rèn)證邏輯,如短信登錄等,都可以通過擴(kuò)展 AuthenticationProvider 來實(shí)現(xiàn),這里的 CAS 登錄當(dāng)然也不例外,這里雖然設(shè)置了一個(gè) userDetailService,但是目的不是為了從數(shù)據(jù)庫中查詢數(shù)據(jù)做校驗(yàn),因?yàn)榈卿浭窃?CAS Server 中進(jìn)行的,這個(gè)的作用,我在后面會做介紹。
  6. CasAuthenticationFilter 則是 CAS 認(rèn)證的過濾器,過濾器將請求攔截下來之后,交由 CasAuthenticationProvider 來做具體處理。
  7. SingleSignOutFilter 表示接受 CAS Server 發(fā)出的注銷請求,所有的注銷請求都將從 CAS Client 轉(zhuǎn)發(fā)到 CAS Server,CAS Server 處理完后,會通知所有的 CAS Client 注銷登錄。
  8. LogoutFilter 則是配置將注銷請求轉(zhuǎn)發(fā)到 CAS Server。

接下來我再來給大家看下我定義的 UserDetailsService:

  1. @Component 
  2. @Primary 
  3. public class UserDetailsServiceImpl implements UserDetailsService{ 
  4.  
  5.     @Override 
  6.     public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { 
  7.         return new User(s, "123"truetruetruetrue
  8.                 AuthorityUtils.createAuthorityList("ROLE_user")); 
  9.     } 

既然是單點(diǎn)登錄,也就是用戶是在 CAS Server 上登錄的,這里的 UserDetailsService 意義在哪里呢?

用戶雖然在 CAS Server 上登錄,但是,登錄成功之后,CAS Client 還是要獲取用戶的基本信息、角色等,以便做進(jìn)一步的權(quán)限控制,所以,這里的 loadUserByUsername 方法中的參數(shù),實(shí)際上就是你從 CAS Server 上登錄成功后獲取到的用戶名,拿著這個(gè)用戶名,去數(shù)據(jù)庫中查詢用戶的相關(guān)信心并返回,方便 CAS Client 在后續(xù)的鑒權(quán)中做進(jìn)一步的使用,這里我為了方便,就沒有去數(shù)據(jù)庫中查詢了,而是直接創(chuàng)建了一個(gè) User 對象返回。

接下來,我們再來看看 Spring Security 的配置:

  1. @Configuration 
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter { 
  3.     @Autowired 
  4.     AuthenticationEntryPoint authenticationEntryPoint; 
  5.     @Autowired 
  6.     AuthenticationProvider authenticationProvider; 
  7.     @Autowired 
  8.     SingleSignOutFilter singleSignOutFilter; 
  9.     @Autowired 
  10.     LogoutFilter logoutFilter; 
  11.     @Autowired 
  12.     CasAuthenticationFilter casAuthenticationFilter; 
  13.  
  14.     @Override 
  15.     protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
  16.         auth.authenticationProvider(authenticationProvider); 
  17.     } 
  18.  
  19.     @Override 
  20.     protected void configure(HttpSecurity http) throws Exception { 
  21.         http.authorizeRequests().antMatchers("/user/**"
  22.                 .hasRole("user"
  23.                 .antMatchers("/login/cas").permitAll() 
  24.                 .anyRequest().authenticated() 
  25.                 .and() 
  26.                 .exceptionHandling() 
  27.                 .authenticationEntryPoint(authenticationEntryPoint) 
  28.                 .and() 
  29.                 .addFilter(casAuthenticationFilter) 
  30.                 .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class) 
  31.                 .addFilterBefore(logoutFilter, LogoutFilter.class); 
  32.     } 

這里的配置就簡單很多了:

  1. 首先配置 authenticationProvider,這個(gè) authenticationProvider 實(shí)際上就是一開始配置的 CasAuthenticationProvider。
  2. 接下來配置 /user/** 格式的路徑需要有 user 角色才能訪問,登錄路徑 /login/cas 可以直接訪問,剩余接口都是登錄成功之后才能訪問。
  3. 最后把 authenticationEntryPoint 配置進(jìn)來,再把自定義的過濾器加進(jìn)來,這些都比較容易我就不多說了。

最后,再提供兩個(gè)測試接口:

  1. @RestController 
  2. public class HelloController { 
  3.     @GetMapping("/hello"
  4.     public String hello() { 
  5.         return "hello"
  6.     } 
  7.     @GetMapping("/user/hello"
  8.     public String user() { 
  9.         return "user"
  10.     } 

OK ,如此之后,我們的 CAS Client 現(xiàn)在就開發(fā)完成了,接下來啟動(dòng) CAS Client,啟動(dòng)成功后,瀏覽器輸入 http://client1.cas.javaboy.org:8080/user/hello 訪問 hello 接口,此時(shí)會自動(dòng)跳轉(zhuǎn)到 CAS Server 上登錄,登錄成功之后,經(jīng)過兩個(gè)重定向,會重新回到 hello 接口。

3.小結(jié)

OK,這就是松哥和大家介紹的 Spring Security + CAS 單點(diǎn)登錄,當(dāng)然,這個(gè)案例中還有很多需要完善的地方,松哥會在后面的文章中繼續(xù)和大家分享完善的方案。

好了 ,本文就說到這里,本文相關(guān)案例我已經(jīng)上傳到 GitHub ,大家可以自行下載:https://github.com/lenve/spring-security-samples

本文轉(zhuǎn)載自微信公眾號「江南一點(diǎn)雨」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系江南一點(diǎn)雨公眾號。

 

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(guān)推薦

2021-07-06 11:42:05

數(shù)據(jù)庫SpringSecurCAS

2021-05-08 10:44:35

SpringSecur登錄詳情

2021-07-13 14:05:37

單點(diǎn)登錄頁面

2021-06-29 12:27:19

Spring BootCAS 登錄

2012-12-03 13:54:15

IBMdW

2022-05-12 07:37:51

單點(diǎn)登錄微服務(wù)開源

2023-08-29 08:00:38

2020-10-18 07:33:58

單點(diǎn)登錄cas-serverkeycloak

2021-04-21 10:38:44

Spring Boot RememberMe安全

2021-05-12 10:39:51

SpringSecurity設(shè)備

2013-10-16 15:17:30

vCenter單點(diǎn)登錄

2020-12-28 05:52:27

SSO登錄單點(diǎn)

2016-12-26 18:05:00

單點(diǎn)登錄原理簡單實(shí)現(xiàn)

2024-03-07 09:20:16

2022-08-15 08:34:08

OauthCAS登錄

2012-08-07 09:04:46

單點(diǎn)登錄云安全云計(jì)算

2024-08-29 10:23:42

2024-06-21 09:28:43

2012-02-14 14:17:35

ibmdw

2021-06-24 08:52:19

單點(diǎn)登錄代碼前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號