springboot 集成cas5.3 實現(xiàn)sso單點登錄詳細流程
什么是單點登錄?
單點登錄(Single Sign On),簡稱為 SSO,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。SSO的定義是在多個應用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統(tǒng)。
我們目前的系統(tǒng)存在諸多子系統(tǒng),而這些子系統(tǒng)是分別部署在不同的服務(wù)器中,那么使用傳統(tǒng)方式的session是無法解決的,我們需要使用相關(guān)的單點登錄技術(shù)來解決。
SSO單點登錄訪問流程主要有以下步驟:
- 訪問服務(wù):SSO客戶端發(fā)送請求訪問應用系統(tǒng)提供的服務(wù)資源。
- 定向認證:SSO客戶端會重定向用戶請求到SSO服務(wù)器。
- 用戶認證:用戶身份認證。
- 發(fā)放票據(jù):SSO服務(wù)器會產(chǎn)生一個隨機的Service Ticket。
- 驗證票據(jù):SSO服務(wù)器驗證票據(jù)Service Ticket的合法性,驗證通過后,允許客戶端訪問服務(wù)。
- 傳輸用戶信息:SSO服務(wù)器驗證票據(jù)通過后,傳輸用戶認證結(jié)果信息給客戶端。

(作者補充:其實簡單來說,cas就是中央認證服務(wù),就是單點登錄,單點登錄簡稱為sso?。?/p>
cas服務(wù)端部署
地址:https://github.com/apereo/cas-overlay-template/tree/5.3
1、解壓下載的zip壓縮包
2、解壓后使用maven命令打包
mvn package
3、把target下生成的war包重命名為cas.war放到tomcat下
4、啟動tomcat
5、找到解壓的文件
由于cas默認使用的是基于https協(xié)議,需要改為兼容使用http協(xié)議,打開對應你的目錄文件:
D:\tomcat8\webapps\cas\WEB-INF\classes\application.properties
修改application.properties文件,添加下面配置,使用http
#使用http協(xié)議 cas.tgc.secure=false cas.serviceRegistry.initFromJson=true #由于https協(xié)議默認使用的端口為8443,還需我們修改為tomcat的8080端口 server.port=8080
修改HTTPSandIMAPS-10000001.json文件
D:\tomcat8\webapps\cas\WEB-INF\classes\services目錄下的HTTPSandIMAPS-10000001.json
把原來的serviceId內(nèi)容改成如下
"serviceId" : "^(https|http|imaps)://.*",
兼容http修改完畢。
修改配置中的登錄用戶名密碼
cas.authn.accept.users=yyh::123456
cas服務(wù)器端搭建完畢,重啟tomcat 進行測試,在瀏覽器中輸入下面地址,進行訪問
http://localhost:8080/cas/login



服務(wù)端就已經(jīng)搭好了,并且可以通過登錄退出了。
cas客戶端搭建
在新建的springboot項目的pom.xml添加如下依賴(匹配對應的版本)
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>2.3.0-GA</version>
</dependency>
在resources下新建application.properties
server.port=8088 #cas服務(wù)端的地址 cas.server-url-prefix=http://localhost:8080/cas #cas服務(wù)端的登錄地址 cas.server-login-url=http://localhost:8080/cas/login #當前服務(wù)器的地址(客戶端) cas.client-host-url=http://localhost:8081 #Ticket校驗器使用Cas30ProxyReceivingTicketValidationFilter cas.validation-type=cas3
Application啟動類上添加注解
import net.unicon.cas.client.configuration.EnableCasClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//啟用cas
@EnableCasClient
@SpringBootApplication
public class CasClient2Application {
public static void main(String[] args) {
SpringApplication.run(CasClient2Application.class, args);
}
}
第一個客戶端的controller
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import static org.jasig.cas.client.util.AbstractCasFilter.CONST_CAS_ASSERTION;
@RestController
public class controller {
@RequestMapping("/sso-test1")
public String test1(HttpSession session){
Assertion assertion = (Assertion)session.getAttribute(CONST_CAS_ASSERTION);
AttributePrincipal principal = assertion.getPrincipal();
String loginName = principal.getName();
return "sso-test1,當前登錄賬戶"+loginName;
}
}
一個客戶端就添加好了,添加另一個客戶端出端口其他基本也是一樣
第二個客戶端的controller
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import static org.jasig.cas.client.util.AbstractCasFilter.CONST_CAS_ASSERTION;
@RestController
public class controller {
@RequestMapping("/sso-test2")
public String test1(HttpSession session){
Assertion assertion = (Assertion)session.getAttribute(CONST_CAS_ASSERTION);
AttributePrincipal principal = assertion.getPrincipal();
String loginName = principal.getName();
return "sso-test222222,當前登錄賬戶"+loginName;
}
}
效果
在沒有登錄的情況下訪問 http://localhost:8081/sso-test1

直接跳到了登錄界面,并且把回調(diào)地址也帶上了
訪問第二個客戶端 http://localhost:8082/sso-test2

跟第一個也是一樣,這次我們隨便登錄一個

登錄后,執(zhí)行了回調(diào)接口,刷新一下第一個客戶端的地址

也登錄成功了。
配置統(tǒng)一登出
添加登出接口controller
/**
* 退出 后自動重定向自定義接口
* @param request
* @return
*/
@RequestMapping("/system/logout1")
public String logout1(HttpServletRequest request) {
HttpSession session = request.getSession();
session.invalidate();
return "redirect:http://localhost:8080/cas/logout?service=http://localhost:8081/system/logoutSuccess";
}
/**
* 退出成功頁
* @return
*/
@RequestMapping("/system/logoutSuccess")
@ResponseBody
public String logoutSuccess() {
return "test1成功退出!";
}
設(shè)置cas認證中心允許重定向跳轉(zhuǎn)
打開你的cas認證中心里的 application.properties 文件,添加如下配置
#退出登錄后允許跳轉(zhuǎn) cas.logout.followServiceRedirects=true
新建config配置文件
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class config {
//cas認證服務(wù)中心地址
private static final String CAS_SERVER_URL_PREFIX = "http://localhost:8080/cas/";
//cas認證服務(wù)中心 系統(tǒng)登錄地址
private static final String CAS_SERVER_URL_LOGIN = "http://localhost:8080/cas/login";
//你自己的客戶端1的地址
private static final String SERVER_NAME = "http://localhost:8081/";
/**
* description: 登錄過濾器
* @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterSingleRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SingleSignOutFilter());
// 設(shè)定匹配的路徑
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
registration.setInitParameters(initParameters);
// 設(shè)定加載的順序
registration.setOrder(1);
return registration;
}
/**
* description:過濾驗證器
* * @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterValidationRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
// 設(shè)定匹配的路徑
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
initParameters.put("serverName", SERVER_NAME);
initParameters.put("useSession", "true");
registration.setInitParameters(initParameters);
// 設(shè)定加載的順序
registration.setOrder(1);
return registration;
}
/**
* description:授權(quán)過濾器
* @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterAuthenticationRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AuthenticationFilter());
// 設(shè)定匹配的路徑
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerLoginUrl", CAS_SERVER_URL_LOGIN);
initParameters.put("serverName", SERVER_NAME);
//設(shè)置忽略 退出登錄不用登錄
initParameters.put("ignorePattern", "/system/*");
registration.setInitParameters(initParameters);
// 設(shè)定加載的順序
registration.setOrder(1);
return registration;
}
/**
* wraper過濾器
* @return
*/
@Bean
public FilterRegistrationBean filterWrapperRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HttpServletRequestWrapperFilter());
// 設(shè)定匹配的路徑
registration.addUrlPatterns("/*");
// 設(shè)定加載的順序
registration.setOrder(1);
return registration;
}
/**
* 添加監(jiān)聽器
* @return
*/
@Bean
public ServletListenerRegistrationBean<EventListener> singleSignOutListenerRegistration(){
ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>();
registrationBean.setListener(new SingleSignOutHttpSessionListener());
registrationBean.setOrder(1);
return registrationBean;
}
}
客戶端2跟客戶端1的大似相同,這樣就可以實現(xiàn)登出一個系統(tǒng),所有系統(tǒng)全部登出。
到此這篇關(guān)于springboot 集成cas5.3 實現(xiàn)sso單點登錄詳細流程的文章就介紹到這了,更多相關(guān)springboot sso單點登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中忽略實體類中的某個屬性不返回給前端的方法(示例詳解)
本文介紹了在Spring Boot中使用Jackson和Fastjson忽略實體類屬性不返回給前端的方法,在Jackson中,同時使用@JsonProperty和@JsonIgnore時,@JsonIgnore可能失效,Fastjson中可以使用@JSONField(serialize=false)來實現(xiàn),本文結(jié)合實例代碼介紹的非常詳細,需要的朋友參考下吧2024-11-11
使用Mybatis-plus實現(xiàn)對數(shù)據(jù)庫表的內(nèi)部字段進行比較
這篇文章主要介紹了使用Mybatis-plus實現(xiàn)對數(shù)據(jù)庫表的內(nèi)部字段進行比較方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
java使用監(jiān)聽器實現(xiàn)一個統(tǒng)計網(wǎng)站在線人數(shù)的示例
本文主要介紹了java使用監(jiān)聽器實現(xiàn)一個統(tǒng)計網(wǎng)站在線人數(shù)的示例,具有一定的參考價值,有需要的朋友可以了解一下。2016-10-10
Lombok 的@StandardException注解解析
@StandardException 是一個實驗性的注解,添加到 Project Lombok 的 v__1.18.22 版本中,在本教程中,我們將使用 Lombok 的 @StandardException 注解自動生成異常類型類的構(gòu)造函數(shù),需要的朋友可以參考下2023-05-05
mybatis中insert返回值為1,但數(shù)據(jù)庫卻沒有數(shù)據(jù)
這篇文章主要介紹了mybatis中insert返回值為1,但數(shù)據(jù)庫卻沒有數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10
SpringBoot下獲取resources目錄下文件的常用方法
本文詳細介紹了SpringBoot獲取resources目錄下文件的常用方法,包括使用this.getClass()方法、ClassPathResource獲取以及hutool工具類ResourceUtil獲取,感興趣的可以了解一下2024-10-10

