国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot 實(shí)現(xiàn)CAS Server統(tǒng)一登錄認(rèn)證

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot 實(shí)現(xiàn)CAS Server統(tǒng)一登錄認(rèn)證。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

SpringBoot 集成CAS Server

一、CAS Service服務(wù)介紹

? CAS(Central Authentication Service)中心授權(quán)服務(wù),是一個(gè)開(kāi)源項(xiàng)目,目的在于為Web應(yīng)用系統(tǒng)提供一種可靠的單點(diǎn)登錄。

? 在整個(gè)認(rèn)證的流程中的整個(gè)流程大概是:首先由CAS Client(我們的客戶端應(yīng)用)發(fā)起請(qǐng)求,CAS Client 會(huì)重定向到CAS Server進(jìn)行登錄,CAS Server進(jìn)行賬戶校驗(yàn)且多個(gè)CAS Client 之間可以共享登錄的 session ,Server 和 Client 是一對(duì)多的關(guān)系?;贑AS的SSO訪問(wèn)流程步驟:

  1. 訪問(wèn)服務(wù): CAS Client 客戶端發(fā)送請(qǐng)求訪問(wèn)應(yīng)用系統(tǒng)提供的服務(wù)資源。
  2. 定向認(rèn)證: CAS Client 客戶端會(huì)重定向用戶請(qǐng)求到 CAS Server 服務(wù)器。
  3. 用戶認(rèn)證: 用戶在瀏覽器端輸入用戶驗(yàn)證信息,CAS Server服務(wù)端完成用戶身份認(rèn)證。
  4. 發(fā)放票據(jù): CAS Server服務(wù)器會(huì)產(chǎn)生一個(gè)隨機(jī)的 Service Ticket 。
  5. 驗(yàn)證票據(jù): CAS Server服務(wù)器驗(yàn)證票據(jù) Service Ticket 的合法性,驗(yàn)證通過(guò)后,允許客戶端訪問(wèn)服務(wù)。
  6. 傳輸用戶信息: CAS Server 服務(wù)器驗(yàn)證票據(jù)通過(guò)后,傳輸用戶認(rèn)證結(jié)果信息給客戶端。

在這里插入圖片描述

? 從結(jié)構(gòu)上看,CAS 包含兩個(gè)部分: CAS ServerCAS Client 。 CAS Server 需要獨(dú)立部署,主要負(fù)責(zé)對(duì)用戶的認(rèn)證工作; CAS Client 負(fù)責(zé)處理對(duì)客戶端受保護(hù)資源的訪問(wèn)請(qǐng)求,需要登錄時(shí),重定向到 CAS Server。

? CAS Client 與受保護(hù)的客戶端應(yīng)用部署在一起,以 Filter 方式保護(hù)受保護(hù)的資源。對(duì)于訪問(wèn)受保護(hù)資源的每個(gè) Web 請(qǐng)求, CAS Client 會(huì)分析該請(qǐng)求的 Http 請(qǐng)求中是否包含 Service Ticket。如果沒(méi)有,則說(shuō)明當(dāng)前用戶尚未登錄,于是將請(qǐng)求重定向到指定好的 CAS Server 登錄地址,并傳遞 Service (也就是要訪問(wèn)的目的資源地址),以便登錄成功過(guò)后轉(zhuǎn)回該地址。

? 在流程圖中的第三步輸入認(rèn)證信息,登陸成功后,CAS Server 隨機(jī)產(chǎn)生一個(gè)相當(dāng)長(zhǎng)度、唯一、不可偽造的 Service Ticket,并緩存以待將來(lái)驗(yàn)證。之后系統(tǒng)自動(dòng)重定向到 Service 所在地址,并為客戶端瀏覽器設(shè)置一個(gè) Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新產(chǎn)生的 Ticket 過(guò)后,在第 5,6 步中與 CAS Server 進(jìn)行身份核實(shí),以確保 Service Ticket 的合法性。

二、CAS Server服務(wù)的搭建

2.1 下載cas-overlay-template

? 這里為大家提供一個(gè) 5.1版本的 git地址:<https://github.com/apereo/cas-overlay-template/tree/5.1

5.3版本的git地址

網(wǎng)上都能找到很多下載方式的,或者私信我 我測(cè)試使用的是cas-overlay-template-5.3

? 獲取到項(xiàng)目后zip的方式解壓出來(lái)后的目錄如下:

在這里插入圖片描述

2.2 使用外部Tomcat部署CAS Server

  • 解壓出來(lái)文件夾之后,就可以進(jìn)行打包運(yùn)行了。在解壓的目錄下打開(kāi)命令行 到安裝目錄下 使用build.cmd run 來(lái)進(jìn)行編譯打包。過(guò)程可能需要花點(diǎn)時(shí)間,

在這里插入圖片描述

  • 在打包完成之后就會(huì)啟動(dòng)我們的CAS Server,但是服務(wù)現(xiàn)在是沒(méi)有正常啟動(dòng)的,因?yàn)镃as server 配置證書(shū)路徑是基于linux的,而我們是在windows環(huán)境下部署,目錄結(jié)構(gòu)不一致導(dǎo)致無(wú)法找到相應(yīng)的文件,如果是linux環(huán)境的話就可以成功啟動(dòng)了。

在這里插入圖片描述

? 啟動(dòng)失?。?/p>

在這里插入圖片描述

打包完成之后會(huì)在解壓的目錄下面多了target文件夾:

在這里插入圖片描述

  • 我們將Cas.war(或者直接使用Cas文件夾) 復(fù)制到本機(jī)的 Tomcat 的 webapp目錄中,啟動(dòng)Tomcat即可

在這里插入圖片描述

啟動(dòng)Tomcat,通過(guò)Tomcat日志就可以看見(jiàn)我們的CAS Server是否啟動(dòng)成功了:

在這里插入圖片描述

然后我們就能訪問(wèn)部署到本地CAS Server 服務(wù)了。通過(guò) 127.0.0.1:8080/cas/login 來(lái)訪問(wèn)CAS服務(wù),這里的地址需要根據(jù)自己的實(shí)際情況來(lái)定(比如你部署的Tomcat服務(wù)默認(rèn)地址8080是否改變過(guò) 等情況):

在這里插入圖片描述

至此我們使用外部Tomcat部署CAS Server服務(wù)就成功了!

這里可以使用默認(rèn)的賬戶密碼(賬:casuser 密: Mellon)進(jìn)行登錄,

至于后續(xù)可能出現(xiàn)的一些疑難雜癥(包括靜態(tài)用戶的設(shè)置、http的支持等),文章下面部門章節(jié)會(huì)進(jìn)行介紹。目前先簡(jiǎn)單的將CAS Server服務(wù)部署上去!

2.3 使用IDEA部署CAS Server

? 在IDEA中我們直接將項(xiàng)目通過(guò)maven工具加載pom文件中的jar包和package命令生成運(yùn)行包target。然后在項(xiàng)目中建立本地項(xiàng)目的src/main/java 和 src/main/resources目錄。最后將target包中的/cas/WEB_INF/classes/services和aplication.properties和log4j2.xml以及/cas/WEB_INF/classes/META-INF復(fù)制到resources目錄中。

  • 首先通過(guò)IDEA將解壓后的CAS Server文件打開(kāi)進(jìn)行打包

    打開(kāi)文件后,首相將項(xiàng)目的mave配置好(File/Settings/Build,…/Build Tools/Maven 中配置好自己本地的maven地址),然后加載pom文件中的Jar包。

    maven配置好之后利用maven對(duì)項(xiàng)目進(jìn)行打包

在這里插入圖片描述

  • 移動(dòng)相關(guān)配置文件

    項(xiàng)目打包完成之后,在項(xiàng)目中創(chuàng)建Java文件夾和resources文件夾,將上述提到的target文件中的4個(gè)文件復(fù)制到我們自己創(chuàng)建的resources目錄下

    在這里插入圖片描述

    ?

  • 給CAS Server 項(xiàng)目配置tomcat服務(wù)

    首先給CAS Server 添加tamcat服務(wù)器

    在這里插入圖片描述

? 配置好Tomcat服務(wù)的地址 以及 端口號(hào)等基本信息在這里插入圖片描述

?

? 部署Tomcat服務(wù)器

在這里插入圖片描述

在這里插入圖片描述

選擇war exploded模式進(jìn)行部署我們的Tomcat,選擇之后,將下面的 Application context 基路徑中的數(shù)據(jù)改為 / 即可。

  • 為CAS Server 配置JDK

    打開(kāi) File/Project Stucture/Project中進(jìn)行設(shè)置

在這里插入圖片描述

所有配置都準(zhǔn)備完畢之后 我們就可以啟動(dòng)Tomcat了,tomcat啟動(dòng)之后就能夠正常訪問(wèn)到我們的CAS Server服務(wù)了!

在這里插入圖片描述

通過(guò) 127.0.0.1:8080/login 即可訪問(wèn)到我們的CAS Service。這里可以使用默認(rèn)的賬戶密碼(賬:casuser 密: Mellon)進(jìn)行登錄。

推出登錄的地址: 127.0.0.1:8080/logout

在這里插入圖片描述

三、CAS Server的其他配置

3.1 CAS Server 去掉https驗(yàn)證

? 這里這樣設(shè)置的目的是為了,后續(xù)我們通過(guò)項(xiàng)目去請(qǐng)求CAS Server 服務(wù)時(shí),能夠通過(guò) http 的方式去訪問(wèn)我們的CAS Server服務(wù)!

? 在CAS Server服務(wù) 4.2版本時(shí)對(duì)整體的架構(gòu)進(jìn)行了一個(gè)優(yōu)化。

允許Http訪問(wèn)CAS Server 的配置設(shè)置:

  • application.properties 文件中的最后一行配置
#忽略https安全協(xié)議,使用 HTTP 協(xié)議
cas.tgc.secure=false
  • src/main/resources/services中的 HTTPSandIMAPS-10000001.json文件
//原數(shù)據(jù)
{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^(https|imaps)://.*",
  "name" : "HTTPS and IMAPS",
  "id" : 10000001,
  "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
  "evaluationOrder" : 10000
}

// 需要將  "serviceId" : "^(https|imaps)://.*",
//修該成為:"serviceId" : "^(https|imaps|http)://.*" 即可!
如果你的CAS Server 服務(wù)的版本號(hào)在4.2 以下的,可以在去查詢一下配置方法,這里就不在記錄 4.2版本以下的修改方式!

3.2 靜態(tài)認(rèn)證用戶的添加

? 靜態(tài)認(rèn)證用戶是通過(guò) WEb-INF\classes\application.properties 文件中去配置的在這里插入圖片描述

? 在配置文件中,我們的認(rèn)證用戶數(shù)量可以添加配置多個(gè),如上圖所示,就配置了兩個(gè)認(rèn)證用戶。

? 如果你是通過(guò)IDEA來(lái)實(shí)現(xiàn)的CAS Server 服務(wù)的部署,那么只需要修改 main/resoources/application.properties文件。

3.3 配置數(shù)據(jù)庫(kù)查詢認(rèn)證用戶

  • 首先是在maven中導(dǎo)入相關(guān)依賴jar
 <dependencies>
        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-support-jdbc</artifactId>
            <version>6.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-support-jdbc-drivers</artifactId>
            <version>6.5.0</version>
        </dependency>
        <!--數(shù)據(jù)庫(kù)驅(qū)動(dòng)-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
    </dependencies>
  • 在通過(guò)application.properties文件中添加下面配置
# 注釋靜態(tài)驗(yàn)證的配置
cas.tgc.secure=false
cas.serviceRegistry.initFromJson=true
 
#加密迭代次數(shù)
cas.authn.jdbc.encode[0].numberOfIterations=3
#該列名的值可替代上面的值,但對(duì)密碼加密時(shí)必須取該值進(jìn)行處理
cas.authn.jdbc.encode[0].numberOfIterationsFieldName=
#鹽值固定列
cas.authn.jdbc.encode[0].saltFieldName=account
#靜態(tài)鹽值
cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=SELECT * FROM user WHERE account =?
#對(duì)處理鹽值后的算法
cas.authn.jdbc.encode[0].algorithmName=MD5
cas.authn.jdbc.encode[0].passwordFieldName=password
cas.authn.jdbc.encode[0].expiredFieldName=expired
cas.authn.jdbc.encode[0].disabledFieldName=disabled
#數(shù)據(jù)庫(kù)連接
cas.authn.jdbc.encode[0].url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&characterEncoding=UTF-8
#cas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQL5Dialect
cas.authn.jdbc.encode[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.encode[0].user=root
cas.authn.jdbc.encode[0].password=123456

同時(shí)我們需要注釋掉 之前配置在application.properties文件中的 靜態(tài)認(rèn)證用戶,即: cas.auth.accept.users=xxxx數(shù)據(jù)需要注釋掉。

3.4 解決未認(rèn)證授權(quán)的服務(wù)

? 在我們的CAS Client 客戶端服務(wù),跳轉(zhuǎn)到CAS Server 進(jìn)行用戶授權(quán)登錄認(rèn)證時(shí),我們的CAS Server 服務(wù)提示:

“未認(rèn)證授權(quán)的服務(wù)
CAS的服務(wù)記錄是空的,沒(méi)有定義服務(wù)。 希望通過(guò)CAS進(jìn)行認(rèn)證的應(yīng)用程序必須在服務(wù)記錄中明確定義?!?/p>

? 出現(xiàn)這種情況的原因是,我們的CAS Server 服務(wù)端中還沒(méi)有定義對(duì)應(yīng)的服務(wù),也就是我們的應(yīng)用服務(wù)(客戶端),需要在CAS Server 服務(wù)端進(jìn)行記錄信息,這樣才能通過(guò)Client客戶端跳轉(zhuǎn)到我CAS Server 服務(wù)端來(lái)進(jìn)行用戶認(rèn)證。

? 對(duì)應(yīng)客戶端在CAS Server 服務(wù)端中是否注冊(cè)成功,通過(guò)我們的CAS Server 服務(wù)啟動(dòng)時(shí)Tomcat的日志也能看出來(lái)。

? 沒(méi)有CAS Client 客戶端注冊(cè)的情況下的日志:

2023-11-09 16:37:59,935 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [InMemoryServiceRegistry].>
2023-11-09 16:38:59,947 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [InMemoryServiceRegistry].>

? CAS Server中注冊(cè)了CAS Client客戶端時(shí),Tomcat的啟動(dòng)日志:

2023-11-09 16:43:15,594 INFO [org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner] - <[0] expired tickets removed.>
2023-11-09 16:44:05,568 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [2] service(s) from [InMemoryServiceRegistry].>
2023-11-09 16:45:05,573 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [2] service(s) from [InMemoryServiceRegistry].>

  • 詳細(xì)的配置過(guò)程:

Client Server 的配置位置: 在 HTTPSandIMAPS-10000001.json 文件中配置我們的客戶端信息。

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^(https|http|imaps)://.*",
  "name" : "HTTPS and IMAPS",
  "id" : 10000001,
  "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
  "evaluationOrder" : 10000
}

配置完json數(shù)據(jù)后,還需要改動(dòng)application.properties 文件中的信息,在改配置文件中添加下面兩行數(shù)據(jù),這樣才能使得我們的CAS Server服務(wù)端能夠讀取到配置的客戶端信息。

#是否開(kāi)啟json識(shí)別功能,默認(rèn)為false
cas.serviceRegistry.initFromJson=true
#忽略https安全協(xié)議,使用 HTTP 協(xié)議
cas.tgc.secure=false

上面兩個(gè)配置完成之后,重啟Tomcat服務(wù)。

在這里插入圖片描述

通過(guò)Tomcat日志可以看出,我們的配置已經(jīng)生效,CAS Server服務(wù)端已經(jīng)讀取到配置文件中的客戶端。

三、SpringBoot集成cas-client-core實(shí)現(xiàn)CAS認(rèn)證

? 在部署完CAS Server 認(rèn)證服務(wù)端之后,我們就需要通過(guò)CAS Client客戶端集成CAS 服務(wù)實(shí)現(xiàn)集成認(rèn)證了。在SpringBoot 中 可以通過(guò)集成CAS-Client即可對(duì)Cas認(rèn)證進(jìn)行集成。

集成這部分文章引薦:https://blog.csdn.net/uziuzi669/article/details/119486588

  • 引入POM依賴

這里需要根據(jù)自己部署的CAS Server 服務(wù)版本選擇合適的依賴版本

<!--Cas單點(diǎn)登錄認(rèn)證-->
<dependency>
    <groupId>org.jasig.cas.client</groupId>
    <artifactId>cas-client-core</artifactId>
    <version>3.5.0</version>
</dependency>
  • CAS集成的核心配置類
package com.wxxssf.CasAuthLogin.casConfig;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.Cas20ProxyReceivingTicketValidationFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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 org.springframework.core.Ordered;

/**
 * @Description: cas集成核心配置類
 * @ClassName: CasConfig
 */
@Configuration
@Slf4j
@ConditionalOnProperty(value ="cas.validation-type",havingValue = "cas") //根據(jù)應(yīng)用程序配置文件中的屬性值來(lái)控制Bean的創(chuàng)建和加載

public class CasConfig {

    /**
    *@Description 需要走cas攔截器的地址
    */
    @Value("${cas.urlPattern:/cas/loginByNameAndCardNo}")
    private String filterUrl;

    /**
     * 默認(rèn)的cas地址,防止通過(guò) 配置信息獲取不到,CAS服務(wù)端的登錄地址,login為固定值
     */
    @Value("${cas.server-url-prefix:https://ciap7.wisedu.com/authserver/login}")
    private String casServerUrl;

    /**
     * 應(yīng)用校驗(yàn)訪問(wèn)地址(這個(gè)地址需要在cas服務(wù)端進(jìn)行配置)
     */
    @Value("${cas.authentication-url:https://ciap7.wisedu.com/authserver}")
    private String authenticationUrl;

    /**
     * 應(yīng)用訪問(wèn)地址(這個(gè)地址需要在cas服務(wù)端進(jìn)行配置)
     */
    @Value("${cas.client-host-url:http://localhost:8090}")
    private String appServerUrl;


    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean() {
        log.info(" servletListenerRegistrationBean  \n cas 單點(diǎn)登錄配置 \n appServerUrl = " + appServerUrl + "\n casServerUrl = " + casServerUrl);
        ServletListenerRegistrationBean listenerRegistrationBean = new ServletListenerRegistrationBean();
        listenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener());
        listenerRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return listenerRegistrationBean;
    }

    /**
     * 單點(diǎn)登錄退出
     */
    @Bean
    public FilterRegistrationBean singleSignOutFilter() {
        log.info(" servletListenerRegistrationBean ");
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new SingleSignOutFilter());
        registrationBean.addUrlPatterns(filterUrl);
        registrationBean.addInitParameter("casServerUrlPrefix", casServerUrl);
        registrationBean.setName("CAS Single Sign Out Filter");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    /**
     * 單點(diǎn)登錄認(rèn)證
     */
    @Bean
    public FilterRegistrationBean AuthenticationFilter() {
        log.info(" AuthenticationFilter ");
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new AuthenticationFilter());
        registrationBean.addUrlPatterns(filterUrl);
        registrationBean.setName("CAS Filter");
        registrationBean.addInitParameter("casServerLoginUrl", casServerUrl);
        registrationBean.addInitParameter("serverName", appServerUrl);
        registrationBean.setOrder(1);
        return registrationBean;
    }

    /**
     * 決定票據(jù)驗(yàn)證過(guò)濾器的版本,默認(rèn)30,old是20版
     */
    @Value("${cas.filterVersion:new}")
    private String filterVersion;


    /**
     * 單點(diǎn)登錄校驗(yàn)
     */
    @Bean
    public FilterRegistrationBean Cas30ProxyReceivingTicketValidationFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        if (StringUtils.isNotBlank(filterVersion) && filterVersion.equals("old")){
            log.info(" Cas20ProxyReceivingTicketValidationFilter ");
            registrationBean.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
        }else {
            log.info(" Cas30ProxyReceivingTicketValidationFilter ");
            registrationBean.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
        }
        registrationBean.addUrlPatterns(filterUrl);
        registrationBean.setName("CAS Validation Filter");
        registrationBean.addInitParameter("casServerUrlPrefix", authenticationUrl);
        registrationBean.addInitParameter("serverName", appServerUrl);
        registrationBean.setOrder(1);
        return registrationBean;
    }

    /**
     * 單點(diǎn)登錄請(qǐng)求包裝
     */
    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter() {
        log.info(" httpServletRequestWrapperFilter ");
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        //registrationBean.setFilter(new HttpServletRequestWrapperFilter());
        registrationBean.setFilter(new HttpServletRequestWrapperFilter());
        registrationBean.addUrlPatterns(filterUrl);
        registrationBean.setName("CAS HttpServletRequest Wrapper Filter");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

? 上面的單點(diǎn)登錄校驗(yàn)器,需要我們創(chuàng)建票據(jù)驗(yàn)證 TicketValidationFiter ,但是需要注意的是票據(jù)驗(yàn)證過(guò)濾器有兩種類型分別是:Cas30ProxyReceivingTicketValidationFilter 和 Cas20ProxyReceivingTicketValidationFilter。

? 在認(rèn)證票據(jù)是會(huì)出現(xiàn)報(bào)錯(cuò)的情況,這時(shí)候就需要考慮這個(gè)票據(jù)驗(yàn)證器TicketValidationFiter的版本問(wèn)題,CAS Server 的版本是否兼容Filter,從而引起沖突問(wèn)題,具體使用哪一種票據(jù)驗(yàn)證器,需要根據(jù)實(shí)際情況去調(diào)整,這個(gè)票據(jù)驗(yàn)證器的選擇也是通過(guò)application.properties配置文件中去實(shí)現(xiàn)的動(dòng)態(tài)選擇。

?

  • 上面的各個(gè)連接地址是通過(guò)application.properties文件進(jìn)行動(dòng)態(tài)配置讀取的,示例如下:
#===Cas集成認(rèn)證===
#需要走攔截器的地址 /api/loginByNameAndCardNo :驗(yàn)票攔截路徑
cas.urlPattern = /cas/loginByNameAndCardNo
# 客戶端如果要登錄,會(huì)跳轉(zhuǎn)到CAS服務(wù)端的登錄地址(認(rèn)證地址) : 認(rèn)證中心登錄頁(yè)面地址   
# http://192.168.0.145:8080/cas/login
cas.server-url-prefix = http://192.168.0.145:8080/cas/login
# CAS 服務(wù)端地址(認(rèn)證平臺(tái)地址):認(rèn)證中心地址  
# http://192.168.0.145:8080/cas
cas.authentication-url = http://192.168.0.145:8080/cas
# 客戶端在CAS服務(wù)端登錄成功后,自動(dòng)從CAS服務(wù)端跳轉(zhuǎn)回客戶端的地址 :應(yīng)用地址,也就是自己的系統(tǒng)地址。 https://cwfw.mtxy.edu.cn
cas.client-host-url = http://192.168.0.145:8998
# Ticket校驗(yàn)器使用 Cas30ProxyReceivingTicketValidationFilter :動(dòng)態(tài)開(kāi)啟 cas 單點(diǎn)登錄
cas.validation-type = cas
# 驗(yàn)票器版本
cas.filterVersion = new
  • CAS認(rèn)證用戶信息Vo類
package com.wxxssf.CasAuthLogin.Vo;
import lombok.Setter;
import java.util.Map;

/**
 * @Description: Cas認(rèn)證用戶信息
 */
@Getter
@Setter
public class CasUserInfo {
    /** 用戶名 */
    private String userName;
    /** 用戶 */
    private String userAccount;
    /** 用戶信息 */
    private Map<String, Object> attributes;
}
  • 認(rèn)證通過(guò)后返回?cái)?shù)據(jù),獲取用戶信息的工具類封裝
package com.wxxssf.CasAuthLogin.casUtils;

import com.wxxssf.CasAuthLogin.Vo.CasUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;

/**
 * @Description: Cas認(rèn)證工具類
 */

@Slf4j
public class CasUtil {

    /**
     * cas client 默認(rèn)的session key  _const_cas_assertion_
     */
    public final static String CAS = "_const_cas_assertion_";

    /**
     * 封裝CasUserInfo
     */
    public static CasUserInfo getCasUserInfoFromCas(HttpServletRequest request) {
        System.out.println("request.toString() = " + request.toString());
        Object object = request.getSession().getAttribute(CAS);
        if (null == object) {
            return null;
        }
        Assertion assertion = (Assertion) object;
        return buildCasUserInfoByCas(assertion);
    }

    /**
     * 構(gòu)建CasUserInfo
     */
    private static CasUserInfo buildCasUserInfoByCas(Assertion assertion) {
        if (null == assertion) {
            log.error(" Cas沒(méi)有獲取到用戶 ");
            return null;
        }
        CasUserInfo casUserInfo = new CasUserInfo();
        String userName = assertion.getPrincipal().getName();
        log.info(" cas對(duì)接登錄用戶= " + userName);
        log.info("用戶消息:"+assertion.getPrincipal().toString());
        casUserInfo.setUserAccount(userName);
        //獲取屬性值
        Map<String, Object> attributes = assertion.getPrincipal().getAttributes();
        Object name = attributes.get("cn");
        casUserInfo.setUserName(name == null ? userName : name.toString());
        casUserInfo.setAttributes(attributes);
        return casUserInfo;
    }

    /**
     * @Description new:獲取用戶信息全部數(shù)據(jù)展示示例:
     *
     * userInfo = {
     * "userAccount":"20220037",
     * "attributes":{"isFromNewLogin":"false",
     *      "authenticationDate":"2023-07-27T09:15:46.799+08:00[GMT+08:00]",
     *      "loginType":"1",
     *      "successfulAuthenticationHandlers":"com.wisedu.minos.config.login.RememberMeUsernamePasswordHandler",
     *      "cn":"xxx",
     *      "userName":"xxx",
     *      "samlAuthenticationStatementAuthMethod":"urn:oasis:names:tc:SAML:1.0:am:unspecified",
     *      "credentialType":"MyRememberMeCaptchaCredential",
     *      "uid":"20220037",
     *      "authenticationMethod":"com.wisedu.minos.config.login.RememberMeUsernamePasswordHandler",
     *      "longTermAuthenticationRequestTokenUsed":"false",
     *      "containerId":"ou=1000001,ou=People",
     *      "cllt":"userNameLogin",
     *      "dllt":"generalLogin"},
     * "userName":"xxx"}
    */
    public static CasUserInfo getUserInfo(HttpServletRequest request){
        Principal userPrincipal = request.getUserPrincipal();
        CasUserInfo casUserInfo = new CasUserInfo();
        if (userPrincipal != null && userPrincipal instanceof AttributePrincipal){
            AttributePrincipal attributePrincipal = (AttributePrincipal) userPrincipal;
            //獲取用戶信息中公開(kāi)的Attributes部分
            Map<String, Object> map = attributePrincipal.getAttributes();
            String cn = (String)map.get("cn");
            String user_name = (String)map.get("userName");
            casUserInfo.setUserAccount(userPrincipal.getName());
            casUserInfo.setAttributes(map);
            casUserInfo.setUserName(cn == null ? userPrincipal.getName() : cn );
        }
        return casUserInfo;
    }
    // TODO: 2023-07-24   AttributePrincipal類和Assertion  區(qū)別~~?。?/span>
}
  • 單點(diǎn)登錄接口
/**
   * cas 單點(diǎn)登錄
   *
   * @param request 請(qǐng)求頭(姓名+身份證號(hào))
   * @param ticket cas 票據(jù)
   * @return
   */
  @GetMapping(value = "/api/loginByNameAndCardNo")
  @ApiOperation("cas單點(diǎn)登錄")
  public String loginByNameAndCardNo(HttpServletRequest request) {
    CasUserInfo userInfo = CasUtil.getCasUserInfoFromCas(request);
    log.info("userInfo = " + JSONObject.toJSON(userInfo));
    String url = "main";
    MadStudent student = new MadStudent();
    student.setName(userInfo.getAttributes().get("Name").toString());
    student.setCardNo(userInfo.getAttributes().get("IdCard").toString());
  	// 登錄用戶校驗(yàn) 
  	// xxxxx
  	// 用戶數(shù)據(jù)為 true
  	// 跳轉(zhuǎn)頁(yè)面
    return "url";
    } else {
      return "redirect:" + casUrl;
    }
  }

四、其他方式實(shí)現(xiàn)的認(rèn)證案例記錄(略):

? :該部分內(nèi)容僅僅為自己記錄使用,可跳過(guò)!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-794904.html

4.1 基于深信服IDTrust 實(shí)現(xiàn)Cas認(rèn)證

  • 方式一:基于JDK的java.net包中已經(jīng)提供了訪問(wèn)Http協(xié)議的 HttpURLConnection 類實(shí)現(xiàn)
<%@ page import="java.net.URL" %>
<%@ page import="java.net.URLConnection" %>
<%@ page import="javax.net.ssl.HttpsURLConnection" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%@ page import="java.net.HttpURLConnection" %>
<%@ page import="javax.net.ssl.SSLSession" %>
<%@ page import="javax.net.ssl.HostnameVerifier" %>
<%@ page import="java.net.URLEncoder" %><%--
  Created by IntelliJ IDEA.
  User: AD
  To change this template use File | Settings | File Templates.
--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                .getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
                .getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }
%>
<%

    String infoMessage =null;
    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            String infoMessage ="Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost();
            System.out.println("info = " + infoMessage);
            return true;
        }
    };
    trustAllHttpsCertificates();
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
	String service = "http://xxxxx:xx/casLoginTicket.jsp"; //回調(diào)地址
    String encode = URLEncoder.encode(service); 
    URL url = new URL("https://xxxx/cas/login?service="+encode);  //認(rèn)證地址
    HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
    httpsURLConnection.setDoInput(true);
    httpsURLConnection.setRequestMethod("GET");
    httpsURLConnection.setRequestProperty("Content-Type","application/json;charset=utf-8");
    System.out.println("準(zhǔn)備執(zhí)行李連接!!");
    httpsURLConnection.connect();
    InputStream inputStream = httpsURLConnection.getInputStream();
    byte[] buff = new byte[1024];
    int len = -1;
    StringBuffer stringBuffer = new StringBuffer();
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    while((len = inputStream.read(buff)) != -1){
        stringBuffer.append(new String(buff,0,len,"utf-8"));
        byteArrayOutputStream.write(buff,0,len);
    }
    System.out.println("stringBuffer = " + stringBuffer);
    System.out.println("byteArrayOutputStream.toString() = " + byteArrayOutputStream.toString());
    //關(guān)閉資源
    byteArrayOutputStream.close();
    inputStream.close();
    httpsURLConnection.disconnect();
    //response.getWriter().write( stringBuffer.toString());
%>
<html>
<head>
    <title>加載中請(qǐng)稍等....</title>
</head>
<script>
    console.log("加載中....")
</script>
<body>
<h3><%=encode%></h3>
<h3><%=stringBuffer%></h3>
</body>
<script>
</script>
</html>
  • 方式二:基于cn.hutool 的http 包中已經(jīng)提供了訪問(wèn)Http協(xié)議的 Hutool-http 類實(shí)現(xiàn)

<%@ page import="cn.hutool.http.HttpRequest" %>
<%@ page import="cn.hutool.http.HttpResponse" %>
<%@ page import="java.net.URLEncoder" %>
<%--
  Created by IntelliJ IDEA.
  User: AD
  To change this template use File | Settings | File Templates.
--%>
<%
    System.out.println("進(jìn)入集成跳轉(zhuǎn)頁(yè)面?。?);
    String service = "http://xxxx:8888/casLoginTicket.jsp";  //回調(diào)地址
    String encode = URLEncoder.encode(service);

    HttpResponse result = HttpRequest
            .get("https://xxxx/cas/login?service="+encode) //CAS認(rèn)證地址
            .header("Content-Type", "application/json;charset=UTF-8")  
            .timeout(60 * 1000)
            .execute();
    int status = result.getStatus();
    System.out.println("status = " + status);
    String body = result.body();
    System.out.println("body = " + body);
    response.getWriter().write(body);
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>加載中請(qǐng)稍等....</title>
</head>
<script>
    console.log("加載中....")
</script>
<body>
<h3><%=status%></h3>
<h3><%=body%></h3>
</body>
<script>
    console.log("請(qǐng)求響應(yīng)數(shù)據(jù)展示:<%=status%>")
</script>
</html>

4.2 基于職教云平臺(tái)的統(tǒng)一認(rèn)證案例

  • 統(tǒng)一認(rèn)證訪問(wèn)主路徑 jsp文件 (該平臺(tái)的認(rèn)證是需要提前申請(qǐng)入駐,然后綁定對(duì)應(yīng)回調(diào)地址和認(rèn)證地址之后才能進(jìn)行認(rèn)證)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%--<%@ page import="org.apache.commons.lang.StringUtils"%>--%>
<%--<%@ page import="com.ibatis.sqlmap.client.SqlMapClient,com.ufgov.midas.yy.util.*,java.util.*"%>--%>
<%--<%@ page import="com.ufgov.midas.qx.util.*,com.ufgov.midas.qx.sqlmap.*,java.sql.*,com.ufgov.midas.pt.common.DAOFactory" %>--%>
<%--<%@ page import="org.ly.uap.client.authentication.AttributePrincipal"%>--%>
<%@ page import="sun.misc.*"%>
<%--應(yīng)用訪問(wèn)主路徑j(luò)sp--%>
<%
	//認(rèn)證地址:
    String url ="https://xxxxxxx/provider/oauth2/authorize?" +
            "response_type=code" +
            "&client_id=XXXX"+
            "&redirect_uri=http://XXXXX:8888/ASXYSSOLoginSuccessNEW.jsp"+
            "&scope=openid";
    //response.sendRedirect(url);
%>
<head>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <link href="css/style.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <title>SSO_RZ_Welcome!!!</title>
    <style>
        .button {
           ......
        }
        .button2:hover {
            box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
        }
        div{
          ....
        }
    </style>
    <script LANGUAGE="JavaScript">
        var url ="<%=url%>"
        // var urlQd = "https://idaastest.gzzjzhy.com/provider/oauth2/authorize?" +
        //     "response_type=code" +
        //     "&client_id=1688831259003981824"+
        //     "&redirect_uri=http://111.85.31.2:8888/ASXYSSOLoginSuccess.jsp"+
        //     "&scope=????";
        function getAuthCode(){
            // alert("跳轉(zhuǎn)統(tǒng)一認(rèn)證URL="+url)
            window.location.href=url;
        }
    </script>
</head>
<body style="background: #fff;">
<div>
</div>
</body>
</html>
<script language="javascript">getAuthCode();</script>

4.3 基于釘釘?shù)募烧J(rèn)證登錄

  • 首先是認(rèn)證訪問(wèn)頁(yè)面代碼
<%@ page contentType="text/html; charset=GBK" language="java" import="java.sql.*" errorPage="" %>

<%@ page import="com.alibaba.fastjson.JSONObject"%> 
<%@ page import="com.dingtalk.api.DefaultDingTalkClient"%> 
<%@ page import="com.dingtalk.api.DingTalkClient"%> 
<%@ page import="com.dingtalk.api.request.OapiGettokenRequest"%> 
<%@ page import="com.dingtalk.api.request.OapiUserGetuserinfoRequest"%> 
<%@ page import="com.dingtalk.api.response.OapiGettokenResponse"%> 
<%@ page import="com.dingtalk.api.request.OapiV2UserGetRequest"%> 
<%@ page import="com.dingtalk.api.response.OapiUserGetuserinfoResponse"%> 
<%@ page import="com.taobao.api.ApiException"%> 
<%@ page import="com.dingtalk.api.response.OapiV2UserGetResponse"%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html> 
<head>
<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
	<%@ page import="java.util.List" %>
	<%@ page import="java.util.Map" %>
	<%@ page import="javax.lang.model.element.NestingKind" %>
	<script language="javascript" src="./des.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>xxxx</title>
<style>
html,body {。。。。。}
#info{}
#down-info{。。。。。}
</style>
<SCRIPT LANGUAGE=javascript>
{
	<%
	if(ckey!=""){
	  //com.ufgov.midas.pt.service.changeLogin cl = new com.ufgov.midas.pt.service.changeLogin();
	  //String skey = cl.MD5(yonghu + sj + ip);
	  String skey = (yonghu + sj + ip);
	  Date now=new Date();
	  SimpleDateFormat f=new SimpleDateFormat("yyyyMMdd");
	  String DateStr = f.format(now);
	  skey = skey.toLowerCase();
	  ckey = ckey.toLowerCase();
	  if("".equals(sj)){
		  sj = DateStr;
	  }

	  String cood = request.getParameter("msg");
	  System.out.println("獲取到的cood值為=" + cood);
//與釘釘進(jìn)行交互
	  if(yonghu == "" || yonghu == null){
	   // 獲取access_token,注意正式代碼要有異常流處理
       DingTalkClient client = new DefaultDingTalkClient("https://xxxxx/gettoken");
       OapiGettokenRequest request1 = new OapiGettokenRequest();
       request1.setAppkey("dingcz1ruaglmqxxxx");
       request1.setAppsecret("nVgvFHLiYiHxxxGmcK-Widi_xp29vIxxxXu71mCkOtxxxxs");
       request1.setHttpMethod("GET");
       OapiGettokenResponse response1 = null;
       try {
           response1 = client.execute(request1);
       } catch (ApiException e) {
           throw new RuntimeException(e);
       }
	   System.out.println("獲取用戶token:response1.getBody() = " + response1.getBody());
       JSONObject jsonObject =JSONObject.parseObject(response1.getBody());
       String access_token = (String) jsonObject.get("access_token");

//獲取用戶id
       DingTalkClient client2 = new DefaultDingTalkClient("https://xxxxx/user/getuserinfo");
       OapiUserGetuserinfoRequest request2 = new OapiUserGetuserinfoRequest();
       //todo--SSO單點(diǎn)登錄授權(quán)碼
       String requestAuthCode = cood;
       request2.setCode(requestAuthCode);
       request2.setHttpMethod("GET");
       OapiUserGetuserinfoResponse response2= null;
       try {
           response2 = client2.execute(request2, access_token);
           System.out.println("獲取用戶id信息info:response2.getBody() = " + response2.getBody());
       } catch (ApiException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
       }
       // 查詢得到當(dāng)前用戶的userId
       // 獲得到userId之后應(yīng)用應(yīng)該處理應(yīng)用自身的登錄會(huì)話管理(session),避免后續(xù)的業(yè)務(wù)交互(前端到應(yīng)用服務(wù)端)每次都要重新獲取用戶身份,提升用戶體驗(yàn)
       String userId = response2.getUserid();
	   System.out.println("userId = " + userId);
//獲取用戶信息
       String userInfo = null;
       try {
           DingTalkClient client3 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
           OapiV2UserGetRequest req = new OapiV2UserGetRequest();
//           req.setUserid("001");
           req.setUserid(userId);
           req.setLanguage("zh_CN");
           OapiV2UserGetResponse rsp = client3.execute(req, access_token);
           System.out.println("獲取用戶資料info:rsp.getBody() = " + rsp.getBody());
           userInfo = rsp.getBody();
       } catch (ApiException e) {
           e.printStackTrace();
       //獲取userid
		   System.out.println("JSONObject.parseObject(userInfo) = " + JSONObject.parseObject(userInfo));
		   JSONObject result  = (JSONObject) JSONObject.parseObject(userInfo).get("result");
		   System.out.println(result.get("userid"));
		   //yonghu = (String) result.get("userid");


	   // 獲取job_number
	   	JSONObject result2  = (JSONObject) JSONObject.parseObject(userInfo).get("result");
		  if (result2 == null){
			  System.out.println("不存在該用戶");
		  }else {
			   //yonghu = (String) result2.get("job_number");
			   //工號(hào)
			   String number =(String) result2.get("job_number");
			   System.out.println("result2.get(\"job_number\") = " +number );
			   yonghu = number;
		  }
		  //role_list:id
		  JSONObject result3 = (JSONObject) JSONObject.parseObject(userInfo).get("result");
		  List roleList = (List) result3.get("role_list");
		  if (roleList.size()>0){
			  Map map =(Map) roleList.get(0);
			  System.out.println("map="+map);
			  //yonghu = map.get("id").toString();
		  }
	  }

	  %>

	  // if (code==""||code==null){
	  //   alert("免登授權(quán)碼獲取失敗!");//免登授權(quán)碼獲取失敗
 	 //    closeWin();
 	 //    return false;
	  // } else
	  if("<%=yonghu%>"=="" || "<%=yonghu%>"==null){
		alert("用戶信息錯(cuò)誤,請(qǐng)重新登錄!");//可能是key值不正確
		alert("yonghu="+"<%=yonghu%>");
		closeWin();
		return false;
	 }else{
		alert("yonghu="+"<%=yonghu%>")
		alert("驗(yàn)證成功自動(dòng)登錄!!")
		alert("用戶登錄名正確!")
	 }
	  <%
	}
	%>
	var uid="<%=yonghu%>";
  	doLogin(productName,uid);
}
</SCRIPT> 
</head>
<body>
	<table border=1 width=100% height=100%><tr><td align="center" valign="middle">
		<div id="u8check">
			<div id="info">	客戶端程序, 請(qǐng)稍候...</div>
		</div>
	</td></tr></table>
</body>
</html><script language="javascript">doCallU8();</script>

到了這里,關(guān)于SpringBoot 實(shí)現(xiàn)CAS Server統(tǒng)一登錄認(rèn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【SpringBoot】自從集成spring-security-oauth2后,實(shí)現(xiàn)統(tǒng)一認(rèn)證授權(quán)so easy!

    【SpringBoot】自從集成spring-security-oauth2后,實(shí)現(xiàn)統(tǒng)一認(rèn)證授權(quán)so easy!

    principal:能唯一標(biāo)識(shí)用戶身份的屬性,一個(gè)用戶可以有多個(gè)principal 如登錄的唯一標(biāo)識(shí), 用戶可以使用用戶名或手機(jī)或郵箱進(jìn)行登錄 ,這些principal是讓別人知道的 credential:憑證,用戶才知道的,簡(jiǎn)單的說(shuō)就是 密碼 如:手機(jī)開(kāi)鎖,可以使用 屏幕密碼 也可以使用 人臉識(shí)別 ,

    2023年04月24日
    瀏覽(17)
  • Springboot+redis實(shí)現(xiàn)token的登錄認(rèn)證

    Springboot+redis實(shí)現(xiàn)token的登錄認(rèn)證

    1.在用戶登錄后,如果要訪問(wèn)其他路徑下的資源的話,我們是否還需要再驗(yàn)證一遍呢?而且我們登陸上系統(tǒng)長(zhǎng)時(shí)間不操作的話還需不需要再次驗(yàn)證?所以這種情況下就很需要token來(lái)實(shí)現(xiàn)登錄功能。并通過(guò)redis(redis是一個(gè)key-value存儲(chǔ)系統(tǒng),它支持存儲(chǔ)的value類型相對(duì)更多,包括

    2023年04月09日
    瀏覽(13)
  • springBoot JWT實(shí)現(xiàn)websocket的token登錄攔截認(rèn)證

    功能:所有關(guān)于websocket的請(qǐng)求必須登錄,實(shí)現(xiàn)websocket需要登錄后才可使用,不登錄不能建立連接。 后臺(tái)spring security配置添加websocket的請(qǐng)求可以匿名訪問(wèn),關(guān)于websocket的請(qǐng)求不要認(rèn)證就可以隨意訪問(wèn),去除匿名訪問(wèn)后,前端在與websocket建立鏈接無(wú)法在請(qǐng)求頭里直接加入Authoriz

    2024年02月13日
    瀏覽(29)
  • Spring Authorization Server入門 (十三) 實(shí)現(xiàn)聯(lián)合身份認(rèn)證,集成Github與Gitee的OAuth登錄

    Spring Authorization Server入門 (十三) 實(shí)現(xiàn)聯(lián)合身份認(rèn)證,集成Github與Gitee的OAuth登錄

    什么是聯(lián)合身份認(rèn)證? ??????通過(guò)Spring Security OAuth2 Client(Login)模塊集成第三方登錄至自己的認(rèn)證服務(wù)中,使用聯(lián)合身份認(rèn)證只需要請(qǐng)求認(rèn)證服務(wù),不通過(guò)前端來(lái)跳轉(zhuǎn)三方的授權(quán)申請(qǐng)鏈接,而是統(tǒng)一通過(guò)認(rèn)證服務(wù)來(lái)跳轉(zhuǎn),只需要維護(hù)Spring Authorization Server中身份認(rèn)證提供商

    2024年02月05日
    瀏覽(42)
  • C#窗體程序連接SQL Server數(shù)據(jù)庫(kù)實(shí)現(xiàn)賬號(hào)登錄、賬號(hào)注冊(cè)、修改密碼、賬號(hào)注銷和實(shí)名認(rèn)證(不定時(shí)更新)

    C#窗體程序連接SQL Server數(shù)據(jù)庫(kù)實(shí)現(xiàn)賬號(hào)登錄、賬號(hào)注冊(cè)、修改密碼、賬號(hào)注銷和實(shí)名認(rèn)證(不定時(shí)更新)

    這是本人用Visual Studio2019做的一個(gè)C#窗體登錄程序,如標(biāo)題所示,它包含了賬號(hào)登錄、注冊(cè)賬號(hào)、修改密碼、注銷賬號(hào)和實(shí)名認(rèn)證五個(gè)功能。對(duì)于有一定基礎(chǔ)知識(shí)的小伙伴來(lái)說(shuō),應(yīng)該不算太難,里面有注釋說(shuō)明,可能咋一看感覺(jué)代碼運(yùn)行的邏輯有點(diǎn)亂,不過(guò)沒(méi)關(guān)系,相信對(duì)你會(huì)

    2024年02月02日
    瀏覽(32)
  • springboot整合security,mybatisPlus,thymeleaf實(shí)現(xiàn)登錄認(rèn)證及用戶,菜單,角色權(quán)限管理

    springboot整合security,mybatisPlus,thymeleaf實(shí)現(xiàn)登錄認(rèn)證及用戶,菜單,角色權(quán)限管理

    本系統(tǒng)為springboot整合security,mybatisPlus,thymeleaf實(shí)現(xiàn)登錄認(rèn)證及用戶,菜單,角色權(quán)限管理。頁(yè)面為極簡(jiǎn)模式,沒(méi)有任何渲染。 源碼:https://gitee.com/qfp17393120407/spring-boot_thymeleaf 架構(gòu)截圖 此處以用戶表為例,其他表數(shù)據(jù)可在源碼獲取。 用戶表 共用屬性 共用屬性自動(dòng)填充配置

    2024年02月07日
    瀏覽(23)
  • springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)(萬(wàn)字長(zhǎng)文)

    springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)(萬(wàn)字長(zhǎng)文)

    目前在國(guó)內(nèi)的后端開(kāi)發(fā)中,常用的安全框架有spring security、shiro?,F(xiàn)在,介紹一款由國(guó)人開(kāi)發(fā)的安全框架Sa-Token。這個(gè)框架完全由國(guó)人開(kāi)發(fā),所提供的Api文檔和一些設(shè)置都是比較符合國(guó)人的開(kāi)發(fā)習(xí)慣的,本次就來(lái)介紹一下如何在spring boot框架中整合Sa-Token框架,以實(shí)現(xiàn)我們最常

    2024年04月27日
    瀏覽(25)
  • 若依微服務(wù)集成CAS,實(shí)現(xiàn)單點(diǎn)登錄

    若依(RuoYi)微服務(wù)是一款基于Spring Cloud Alibaba開(kāi)發(fā)的企業(yè)級(jí)微服務(wù)框架,采用前后端分離方式,使用了常用的微服務(wù)組件,如Feign、Nacos、Sentinel、Seata等,提供了豐富的微服務(wù)治理功能,如服務(wù)注冊(cè)、發(fā)現(xiàn)、路由、負(fù)載均衡、熔斷降級(jí)、限流等。借助若依微服務(wù)框架可以讓我

    2024年02月12日
    瀏覽(19)
  • 多系統(tǒng)使用CAS實(shí)現(xiàn)SSO登錄案例

    多系統(tǒng)使用CAS實(shí)現(xiàn)SSO登錄案例

    實(shí)現(xiàn)SSO有很多種方案,比較簡(jiǎn)單且可行的一般都是如上兩種再加上CAS,一般企業(yè)內(nèi)部多個(gè)系統(tǒng)之間如果想實(shí)現(xiàn)SSO,比較推薦的方式就是今天要介紹的CAS,Central Authentication Service,中央身份認(rèn)證服務(wù)。 CAS方案主要包含如下兩個(gè)部分: CAS Server,作為認(rèn)證服務(wù)的中心,需要單獨(dú)部

    2024年02月15日
    瀏覽(25)
  • SpringBoot 基于 OAuth2 統(tǒng)一身份認(rèn)證流程詳解

    SpringBoot 基于 OAuth2 統(tǒng)一身份認(rèn)證流程詳解

    了解OAUTH2統(tǒng)一認(rèn)證基本概念 了解OAUTH2協(xié)議流程 了解OAUTH2各種模式類型 了解Spring Security OAuth設(shè)計(jì) 2. 分析 傳統(tǒng)登陸認(rèn)證介紹 單點(diǎn)登陸認(rèn)證介紹 OAuth2簡(jiǎn)介 OAuth2角色 OAuth2協(xié)議流程介紹 OAuth2授權(quán)類型 OAuth2授權(quán)碼模式流程 OAuth2簡(jiǎn)化模式 OAuth2密碼模式 OAuth2客戶端模式 Spring Security

    2024年02月15日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包