SpringBoot 整合 SpringSecurity 之起源篇(零)

小灰灰blog 發佈 2019-12-30T05:42:56+00:00

本篇為SpringSecurity的第一篇,主要來介紹下什麼是SpringSecurity,以及在springboot中如何使用它<!-- more -->I. 基本知識點官方文檔: https://docs.spring.

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

<!-- more -->

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重定向到登錄頁面了,如下圖

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.name和spring.security.user.password來指定用戶名密碼
  • 通過HttpServletRequest#getRemoteUser()獲取登錄用戶

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

II. 其他

0. 項目

  • 工程:https://github.com/liuyueyi/spring-boot-demo
  • 代碼: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-security/000-basic-demo

1. 一灰灰Blog

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

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

  • 一灰灰Blog個人博客 https://blog.hhui.top
  • 一灰灰Blog-Spring專題博客 http://spring.hhui.top
關鍵字: