簡簡單單聊下SSO(單點登陸)

簡簡單單聊下SSO(單點登陸)

前言

這段時間斷斷續續學習了單點登陸的相關知識,這裏彙總一下,加深下記憶。java

什麼是單點登陸

單點登陸(Single Sign On,簡稱SSO) 是當前比較流行的一種用於企業業務整合的解決方案。mysql

SSO並不具體指哪種框架,而是一種思想。企業裏,若是想讓用戶只登陸一次,就能夠訪問全部互相信任的應用系統時,咱們就能夠採用SSO。git

例如阿里下有淘寶網、天貓網、聚划算等網站。當咱們在其中一個網站登陸了,在同個瀏覽器訪問其餘的幾個網站時,就無需再進行登陸。github

單點登陸的時序圖

如下根據我本身的理解畫的兩個時序圖,來簡單介紹下單點登陸中,用戶登陸認證流程和用戶註銷流程。web

用戶登陸認證流程:算法

cc0eb6b2c6c35442f6ad734559044131.jpeg


用戶註銷流程:spring

340b0d85ee16c28547e92a6ce0a163aa.jpeg


什麼是CAS

CAS(Cantral Authentication Service)是耶魯大學發起的一個開源項目(github地址爲https://github.com/apereo/cas),是單點登陸的實現方式之一。sql

CAS分爲CAS服務端和CAS客戶端。數據庫

CAS服務端負責完成對用戶的認證工做,CAS服務端須要獨立部署。apache

CAS客戶端集成到每一個應用系統上。當用戶須要在認證以後才能訪問應用系統受保護資源時,應用系統判斷該用戶是否已認證,若是沒有認證,則重定向到CAS服務端進行身份認證。

CAS協議能適配大多數語言編寫的應用系統,所以應用十分普遍。

採用CAS實現單點登陸

如下演示搭建CAS,基礎環境爲:JDK1.八、tomcat8.五、apache-maven-3.6.1。

修改hosts文件

因爲是在本地搭建,所以我在hosts文件,添加如下三個域名,解析到172.0.0.1。方便後續區分是客戶端仍是服務端。

127.0.0.1 cas.server.com
127.0.0.1 cas.client.a.com
127.0.0.1 cas.client.b.com

ed3413a3b7f42329115a147d40c48e81.jpg

搭建CAS服務端

一、從github上下載cas-overlay-template(地址:https://github.com/apereo/cas-overlay-template/tree/5.3),此處使用5.3版本。

457ea15aa2b529df0049429aee0c2f86.jpeg


二、使用maven命令打包(須要在本地安裝Maven)。Windows下爲.\build.cmd package,Linux下爲./build.sh package。打包後的war包在target目錄下。

5a709e1ce65a352959efcdebfa3523ac.jpeg

三、因爲cas-server-webapp-tomcat-5.3.14.war很大,下載比較慢。能夠直接到 http://oss.sonatype.org/ 找到對應版本的war包。下載後放到本地Maven倉庫的對應位置便可。

1b2e383899c87de401ccb684d2996351.jpege85f98a6ed956fe8d56154d0f4bd2121.jpeg


四、因爲CAS默認使用的是基於https協議。部署CAS服務端時,須要添加證書,或者改成兼容使用http協議。這裏爲了方便,直接修改war包的配置文件,兼容使用http協議。

4.1 在cas.war部署包下找到\WEB-INF\classes\application.properties添加:

cas.tgc.secure=false
cas.serviceRegistry.initFromJson=true

3d90f6b5e9d120884f12bbda507bd620.jpeg


4.2 在cas.war部署包下找到\WEB-INF\classes\services\HTTPSandIMAPS-10000001.json,修改 serviceId 的值,添加http:

"serviceId" : "^(https|http|imaps)://.*",

a5a2f508a20966062b883a0b04889aa9.jpeg


五、在cas.war部署包下找到\WEB-INF\classes\application.properties,將server.port修改成8080。

5ef2c69732487a192c42df57423c6451.jpeg


六、將修改後的cas.war包放到tomcat的webapps目錄下,啓動tomcat,在瀏覽器中輸入http://localhost:8080/cas,默認用戶名:casuser,默認密碼:Mellon。若是要修改密碼,能夠修改\WEB-INF\classes\application.properties文件。

4ac9b0fcb21017fd6b97beb61b4a1dcf.jpeg

cas服務登陸界面以下圖:

image.png


配置CAS服務端數據庫

上面是經過寫在配置文件中的用戶名和密碼進行登陸的,咱們能夠修改成從數據庫中獲取。

一、修改CAS項目的pox.xml,添加如下依賴。

<dependency>
	<groupId>org.apereo.cas</groupId>
	<artifactId>cas-server-support-jdbc-drivers</artifactId>
	<version>${cas.version}</version>
</dependency>
<dependency>
	<groupId>org.apereo.cas</groupId>
	<artifactId>cas-server-support-jdbc</artifactId>
	<version>${cas.version}</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.46</version>
</dependency>

二、根據搭建CAS服務端章節,從新打包部署包。

三、修改在cas.war部署包下的\WEB-INF\classes\application.properties文件。

3.1 註釋掉默認的用戶# cas.authn.accept.users=casuser::Mellon

3.2 添加如下內容,具體配置含義,能夠到官方文檔查看。

cas.authn.jdbc.query[0].url=jdbc:mysql://{mysql.IP}:3306/{db.name}?useUnicode=true&characterEncoding=utf-8
cas.authn.jdbc.query[0].user={username}
cas.authn.jdbc.query[0].password={password}
# 指定查詢帳號密碼sql
cas.authn.jdbc.query[0].sql=select * from user where username=?
# 指定密碼字段
cas.authn.jdbc.query[0].fieldPassword=password
# 數據庫驅動
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver

#密碼加密策略,若是密碼字段沒有加密,則這一段配置能夠省略
# 默認加密策略
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
# 指定密碼字段加密算法爲MD5
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5

四、修改war包後,根據搭建CAS服務端章節,從新部署。輸入數據庫中的帳號和密碼,便可成功登陸。

搭建CAS客戶端

本部分參考SpringBoot整合CAS單點登陸 搭建。

搭建的客戶端代碼,存放在個人github倉庫

一、使用springboot,搭建web項目,項目名叫cas-client-A,而且引入如下依賴。

<dependency>
    <groupId>net.unicon.cas</groupId>
    <artifactId>cas-client-autoconfig-support</artifactId>
    <version>1.4.0-GA</version>
</dependency>

二、在啓動類添加註解@EnableCasClient

三、在配置文件,添加如下配置。

cas.server-url-prefix=http://cas.server.com:8080/cas
cas.client-host-url=http://cas.client.a.com:9001
server.port=9001
# 填CAS服務器的登陸地址
cas.server-login-url=http://cas.server.com:8080/cas/login
#自定義的退出url,退出成功後跳轉路徑
casClientLogoutUrl=http://cas.server.com:8080/cas/logout

四、添加過濾器,用於從請求中獲取用戶CAS登陸信息,生成本地用戶登陸信息。

public class LocalUserInfoFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request_ = (HttpServletRequest) request;
        String loginName = getAccountNameFromCas(request_);
        if (!StringUtils.isEmpty(loginName)) {
            request_.getSession().setAttribute("loginName", loginName);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

    /**
     * 從cas中獲取用戶名
     *
     * @param request
     * @return
     */
    private static String getAccountNameFromCas(HttpServletRequest request) {
        Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
        if (assertion != null) {
            AttributePrincipal principal = assertion.getPrincipal();
            return principal.getName();
        } else return null;
    }
}

五、添加cas配置類。

@Configuration
public class FilterConfig {
    @Value("${cas.server-url-prefix}")
    private String CAS_URL;
    @Value("${cas.client-host-url}")
    private String APP_URL;
    /**
     * 單點登陸退出
     */
    @Bean
    public FilterRegistrationBean singleSignOutFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new SingleSignOutFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.addInitParameter("casServerUrlPrefix", CAS_URL);
        registrationBean.setName("CAS Single Sign Out Filter");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    /**
     * 從request中獲取cas登陸信息,根據登陸信息獲取當前用戶,建立本地session
     */
    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new LocalUserInfoFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("localUserInfoFilter");
        registrationBean.setOrder(2);
        return registrationBean;
    }

}

六、添加controller。當用戶登陸後,訪問/,返回當前系統的端口號。當用戶訪問/logout,調用cas服務端註銷URL,註銷登陸。

@RestController
public class TestController {


    @Value("${server.port}")
    private String serverPort;

    @Value("${casClientLogoutUrl}")
    private String clientLogoutUrl;

    @GetMapping("/")
    public String hello() {
        return "我是VIP:" + serverPort;
    }


    @GetMapping("/logout")
    public void logout(HttpSession session, HttpServletResponse response)throws Exception {
        session.invalidate();//銷燬session
        //使用cas退出成功後,跳轉頁面
        response.sendRedirect(clientLogoutUrl);
    }

}

七、根據步驟1-7,建立cas-client-B項目,項目配置文件的 cas.client-host-url 和  server.port 修改成下面兩個值。

cas.client-host-url=http://cas.client.b.com:9002
server.port=9002
相關文章
相關標籤/搜索