成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringSecurity系列之SpringBoot+CAS單點登錄

開發 架構
某一個 Client 需要接入 CAS Server 進行驗證,則該 Client 必須提前在 CAS Server 上配置其信息。這個信息既可以動態添加,也可以通過 JSON 來配置,后面松哥會教搭建如何動態添加,這里方便起見,我們還是通過 JSON 來進行配置。

 [[408875]]

1.準備工作

準備工作主要做兩件事。

1.1 服務記錄

某一個 Client 需要接入 CAS Server 進行驗證,則該 Client 必須提前在 CAS Server 上配置其信息。

這個信息既可以動態添加,也可以通過 JSON 來配置,后面松哥會教搭建如何動態添加,這里方便起見,我們還是通過 JSON 來進行配置。

具體配置方式如下,在 CAS Server 中創建如下目錄:

  1. src/main/resources/services 

在該目錄下創建一個名為 client1-99.json 的文件,client1 表示要接入的 client 的名字,99 表示要接入的 client 的 id,json 文件內容如下(這個配置可以參考官方給出的模版: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""應用1 的定義信息"
  6.   "evaluationOrder": 1 

這段 JSON 配置含義如下:

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

接下來再在 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 啟動成功后,我們在控制臺看到如下日志,表示 JSON 配置已經加載成功了:

1.2 JDK 證書

第二個要提前準備的東西就是 JDK 證書。

在實際開發中,這一步可以忽略,但是因為我們現在用的自己生成的 SSL 證書,所以我們要將自己生成的證書導入到 JDK 中,否則在使用 Spring Security 接入 CAS 單點登錄時,會拋出如下錯誤:

[[408877]]

將 SSL 證書導入 JDK 中的命令其實也很簡單,兩個步驟,第一個導出 .cer 文件,第二步,導入 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 

注意,在執行 export 導出命令時,需要輸入密鑰口令,這個口令就是自己一開始創建 SSL 證書時設置的。在執行 import 導入命令時,也需要輸入口令,這個口令是 changeit,注意,不是自己一開始設置的。

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

我們在本地測試一定要導入證書到 JDK 證書庫中,否則后面的測試會出現上圖中的錯誤,證書導入 JDK 證書庫之后,要確保之后的開發中,使用的是本地的 JDK。

注意,JDK 證書導入之后,CASServer 需要重啟一下。

1.3 修改 hosts

另外,我們還需要修改電腦 hosts 文件,因為前面關于 CAS Server,關于 SSL 證書的配置都涉及到域名,所以后面的訪問我們將通過域名的形式訪問,hosts 文件中添加如下兩條記錄:

第一個是 CAS Server 的請求域名,第二個是 CAS Client 的請求域名。

2.開發 Client

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

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

首先我們來創建一個普通的 Spring Boot 項目,加入 Web 依賴 和 Spring Security 依賴,如下:

項目創建成功后,我們再來手動加入 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 的登錄和注銷地址。

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

這里我創建兩個類分別用來接收 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 

另外記得在啟動類上面添加 @ConfigurationPropertiesScan 注解來掃描這兩個配置類:

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

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

接下來創建 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.     } 

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

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

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

用戶雖然在 CAS Server 上登錄,但是,登錄成功之后,CAS Client 還是要獲取用戶的基本信息、角色等,以便做進一步的權限控制,所以,這里的 loadUserByUsername 方法中的參數,實際上就是你從 CAS Server 上登錄成功后獲取到的用戶名,拿著這個用戶名,去數據庫中查詢用戶的相關信心并返回,方便 CAS Client 在后續的鑒權中做進一步的使用,這里我為了方便,就沒有去數據庫中查詢了,而是直接創建了一個 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,這個 authenticationProvider 實際上就是一開始配置的 CasAuthenticationProvider。
  2. 接下來配置 /user/** 格式的路徑需要有 user 角色才能訪問,登錄路徑 /login/cas 可以直接訪問,剩余接口都是登錄成功之后才能訪問。
  3. 最后把 authenticationEntryPoint 配置進來,再把自定義的過濾器加進來,這些都比較容易我就不多說了。

最后,再提供兩個測試接口:

  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 現在就開發完成了,接下來啟動 CAS Client,啟動成功后,瀏覽器輸入 http://client1.cas.javaboy.org:8080/user/hello 訪問 hello 接口,此時會自動跳轉到 CAS Server 上登錄,登錄成功之后,經過兩個重定向,會重新回到 hello 接口。

3.小結

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

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

本文轉載自微信公眾號「江南一點雨」,可以通過以下二維碼關注。轉載本文請聯系江南一點雨公眾號。

 

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2021-07-06 11:42:05

數據庫SpringSecurCAS

2021-05-08 10:44:35

SpringSecur登錄詳情

2021-07-13 14:05:37

單點登錄頁面

2021-06-29 12:27:19

Spring BootCAS 登錄

2012-12-03 13:54:15

IBMdW

2022-05-12 07:37:51

單點登錄微服務開源

2023-08-29 08:00:38

2021-04-21 10:38:44

Spring Boot RememberMe安全

2020-10-18 07:33:58

單點登錄cas-serverkeycloak

2021-05-12 10:39:51

SpringSecurity設備

2020-12-28 05:52:27

SSO登錄單點

2016-12-26 18:05:00

單點登錄原理簡單實現

2013-10-16 15:17:30

vCenter單點登錄

2022-08-15 08:34:08

OauthCAS登錄

2024-03-07 09:20:16

2012-08-07 09:04:46

單點登錄云安全云計算

2024-08-29 10:23:42

2024-06-21 09:28:43

2012-02-14 14:17:35

ibmdw

2021-01-18 06:21:18

登錄SSO接口
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人a视频片观看免费 | 四虎影音| 成人免费视频一区 | 超碰av免费| 一级黄色片免费 | 免费一级欧美在线观看视频 | 久久精品二区亚洲w码 | 国产亚洲精品久久久久久豆腐 | 在线精品一区 | 黄视频网站免费观看 | 欧美黄a| 一级毛片黄片 | 精品久久电影 | 蜜桃视频在线观看www社区 | 免费视频一区二区三区在线观看 | 老司机狠狠爱 | 亚洲一区二区三区在线播放 | 天堂一区| 精品视频国产 | 国产精品一区二区在线 | 亚洲精品www久久久久久广东 | 狠狠干av | 欧美精品首页 | 浴室洗澡偷拍一区二区 | 一二三四av | 中文字幕视频一区 | 欧美二区乱c黑人 | 91大神xh98xh系列全部 | 日韩高清国产一区在线 | 女同久久另类99精品国产 | 日本免费黄色一级片 | www.久久国产精品 | 国产精品视频免费看 | 日本高清中文字幕 | 日韩精品免费在线观看 | 91色视频在线观看 | 污免费网站 | 国产精品一区二区三区久久久 | 久久久精品影院 | 欧美激情黄色 | 国产精品国产成人国产三级 |