Spring Security OAuth2:SSO單點登錄


接着上一篇博客:https://www.cnblogs.com/wwjj4811/p/14505886.html

概述

單點登錄SSO(Single Sign On)說得簡單點就是在一個多系統共存的環境下,用戶在一處登錄后,就不用在其他系統中登錄,也就是用戶的一次登錄能得到其他所有系統的信任。單點登錄在大型網站里使用得非常頻繁,例如像阿里巴巴這樣的網站,在網站的背后是成百上千的子系統,用戶一次操作或交易可能涉及到幾十個子系統的協作,如果每個子系統都需要用戶認證,不僅用戶會瘋掉,各子系統也會為這種重復認證授權的邏輯搞瘋掉

准備工作

sql

向oauth_client_detials表添加兩條數據

INSERT INTO `study-security`.`oauth_client_details`(`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`) VALUES ('client1', NULL, '$2a$10$fTo73KCRzU3HXcPGtaTmxu9zDIrnoud6GvhlKF0sIxWzm7awSkGOK', 'MEMBER_READ,MEMBER_WRITE', 'authorization_code,refresh_code', 'http://localhost:9001/login', NULL, 50000, NULL, NULL, 'true');
INSERT INTO `study-security`.`oauth_client_details`(`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`) VALUES ('client2', NULL, '$2a$10$fTo73KCRzU3HXcPGtaTmxu9zDIrnoud6GvhlKF0sIxWzm7awSkGOK', 'MEMBER_READ', 'authorization_code,refresh_code', 'http://localhost:9002/login', NULL, 50000, NULL, NULL, 'true');

SSO 會員客戶端1

創建cloud-oauth2-sso-client1模塊,pom.xml如下:

    <dependencies>
        <dependency>
            <groupId>com.wj</groupId>
            <artifactId>cloud-oauth2-base</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <!-- 注冊到 Eureka
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
         -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

application.yml

server:
  port: 9001

spring:
  thymeleaf:
    cache: false

security:
  oauth2:
    client:
      client-id: client1 # 當前客戶端id
      client-secret: wj-secret # 客戶端的密碼
      user-authorization-uri: http://localhost:8090/auth/oauth/authorize #請求認證的地址,獲取授權碼地址
      access-token-uri: http://localhost:8090/auth/oauth/token # 請求令牌的地址
    resource:
      jwt:
        # 當用戶授權之后會響應一個授權碼,重定向到當前應用的 http://localhost:9001/login?code=xxx
        # 自動的會對 /login 去獲取令牌,獲取到令牌后會通過 key-uri 獲取到的公鑰進行解密然后本地身份認證和授權(Session)
        key-uri: http://localhost:8090/auth/oauth/token_key # 獲取公鑰

主啟動類和控制器

@SpringBootApplication
public class SsoClient1Application {

    public static void main(String[] args) {
        SpringApplication.run(SsoClient1Application.class, args);
    }
}

@Controller
public class MainController {

    @GetMapping("/")
    public String index(){
        return "index";
    }

    @GetMapping("/member")
    public String member(){
        return "member";
    }
}

創建前端html,兩個頁面都放到templates下面

image-20210310093841210

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>sso1 首頁</title>
</head>
<body>
    <h1>
        <a th:href="@{/member}">客戶端1-查看會員</a>
    </h1>
</body>
</html>

member.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
    <div>
        <h1>客戶端1,歡迎您![[${#authentication.name}]]</h1>
        <h3><a th:href="@{/logout}">退出系統</a></h3>
    </div>
</body>
</html>

sso登陸配置類:

@Configuration
@EnableOAuth2Sso
public class SsoSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //首頁所有人可以訪問
                .antMatchers("/").permitAll()
                .anyRequest().authenticated();
    }
}

SSO 會員客戶端2

創建模塊cloud-oauth2-sso-client2

cloud-oauth2-sso-client2和cloud-oauth2-sso-client1基本一樣,端口號從9001改成9002,所有client1改成client2

單點登陸測試

先啟動認證服務器,再啟動sso客戶端,否則會直接報錯。因為客戶端啟動時會去發送請求獲取公鑰。

image-20210310094944486

先進入http://localhost:9001/,點擊

image-20210310095133623

因為沒有登陸,所以直接跳轉到登錄頁面,這里的登錄頁是認證服務器的,賬號密碼是 admin/1234

image-20210310095224851

登陸成功后,跳轉到member頁面

image-20210310095336165

這時候我們直接訪問:http://localhost:9002/member,發現直接訪問成功,不需要登陸,sso單點登錄整合成功

image-20210310095546311

SSO 退出系統

在單點登陸系統中,我們希望退出登陸當前系統后,將所有客戶端都退出,我們修改配置SsoSecurityConfig:

@Configuration
@EnableOAuth2Sso
public class SsoSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //首頁所有人可以訪問
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                //當前應用退出
                .logout()
                //退出成功后,跳轉到認證服務器退出
                .logoutSuccessUrl("http://localhost:8090/auth/logout")
                .and().csrf().disable();
    }
}

測試:

我們先在sso1客戶端中退出,點擊退出系統

image-20210310100121849

再點擊logout out

image-20210310100143299

然后就跳轉到認證服務器的登陸頁面了

image-20210310100213193

這時候我們再刷新sso2客戶端的頁面,就發現需要重新登陸了

image-20210310100241124

至此,Spring Security OAuth2的單點登陸整合完畢,單次登陸,處處登陸;單次退出,處處退出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM