SpringBoot 整合 SpringSecurity 之起源篇(零)

SpringBoot 整合 SpringSecurity 之起源篇(零)

本篇爲SpringSecurity的第一篇,主要來介紹下什麼是SpringSecurity,以及在springboot中如何使用它

I. 基本知識點

官方文檔: https://docs.spring.io/spring-security/site/docs/5.2.2.BUILD-SNAPSHOT/reference/htmlsingle/#community-help

下面是官方介紹

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

用國語,簡單抽象的說一下它的定義

  • 很🐂的認證和訪問權限校驗框架

那麼具體能幹嘛?

  • 用戶登錄認證:用戶名+密碼登錄,確定用戶身份
  • 用戶訪問鑑權(常見的ACL訪問控制列表,RBAC角色訪問控制):判定是否有權限訪問某個資源
  • 安全保護(CSRF跨站點攻擊,Session Fixation會話固定攻擊…)

II. 初體驗

接下來我們看一下再springboot中如何使用springsecurity

1. 配置

首先得是spring boot項目,然後添加上security的依賴即可,相對完整的pom配置如下(注意我們使用的springboot版本爲2.2.1.RELEASE)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/libs-release-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

2. 實例demo

上面配置完之後,啥都不需要幹,項目已經接入了spring security;項目中的服務都需要登錄之後才能訪問

// 程序啓動類
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// rest 服務
@RestController
public class IndexRest {

    @GetMapping(path = {"/", "/index"})
    public String index() {
        return "hello this is index!";
    }

    @GetMapping(path = "hello")
    public String hello(String name) {
        return "welcome " + name;
    }
}

當我們需要訪問首頁時,會發現直接302重定向到登錄頁面了,如下圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZRLy8z7b-1577668494068)(https://spring.hhui.top/spring-blog/imgs/191223/00.gif)]

spring security默認給我們生成了一個用戶名爲user,密碼爲控制檯中輸出的一行日誌如Using generated security password: aa410186-5c04-4282-b217-507ffb1f61eb

登錄之後會重定向回我們之前訪問的url,通過抓包可以看到,登錄成功之後,會設置請求方的cookie,後續的請求攜帶cookie來表明用戶身份

3. 基本配置

上面雖然演示了一個hello world的初體驗項目,但是這個默認的用戶名/密碼有點鬼畜,默認的配置主要來自於org.springframework.boot.autoconfigure.security.SecurityProperties.User,下面是截圖(所以前面的用戶名爲user)

接下來我們需要配置爲對人類友好的方式,在項目的配置文件application.yml中,指定登錄的用戶名/密碼

spring:
  security:
    user:
      name: yihuihui
      password: 123456

重啓測試項目,使用新的用戶名/密碼(yihuihui/123456)就可以登錄成功了;

4. 用戶身份獲取

上面雖然是一個簡單的case,但還有一點不得不提一下,在我的接口中,雖然知道你登錄了,但怎麼知道你是誰呢?

我們可以直接通過HttpServletRequest#getRemoteUser()的方法來獲取登錄用戶; 或者通過SecurityContextHolder.getContext().getAuthentication().getPrincipal()來獲取授權信息

我們來寫一個通用方法

public String getUser() {
    return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getRemoteUser();
}

// or
public Object getUser() {
    SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}

然後稍微改一下我們的服務接口

@GetMapping(path = {"/", "/index"})
public String index() {
    return "hello this is index! welcome " + getUser();
}

再次訪問之後,結果如下

5. 小結

本文主要是spring security系列的起源篇,第一節介紹了下什麼是SpringSecurity,有什麼特點

  • spring security是一個很🐂🍺的認證(可以簡單理解爲登錄驗證)和鑑權(可簡單理解爲訪問控制)框架
  • 三大特點:登錄 + 鑑權 + 安全防護

第二節介紹了一個簡單入門的HelloWorld實例

  • springboot項目,添加依賴 spring-boot-starter-security; 所有的http接口訪問都需要登錄,默認提供一個用戶名爲user,密碼爲控制檯輸出的UUID字符串
  • 通過spring.security.user.namespring.security.user.password來指定用戶名密碼
  • 通過HttpServletRequest#getRemoteUser()獲取登錄用戶

那麼問題來了,什麼系統可能只有一個用戶呢?要多用戶怎麼辦?不同的用戶不同的權限怎麼辦?某些接口所有人都可以訪問又怎麼辦?

II. 其他

0. 項目

1. 一灰灰Blog

盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

下面一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

一灰灰blog

發佈了197 篇原創文章 · 獲贊 50 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章