鑑權模塊springboot使用springsecurity
以前用spring整合security之後,因爲自以爲對springsecurity比較熟悉,所以一直沒有好好總結過。現在的系統一般都會採用springboot來構建,所以現在打算來講講在springboot裏面如何整合springsecurity。
前言
在偉大的spring時代,springsecurity就已經作爲spring嫡系的鑑權框架,走進了廣大程序員們的視野。相比於其他的鑑權框架來說,springsecuity的優勢非常明顯,功能強大且,鑑權力度較細,能和spring無縫接軌,幾乎可以滿足所有的業務需要,但它也有一些缺點,比如不易理解,當然,這是相對於同樣在一些單點應用上是非流行的另一框架shero來說的。
然而,隨着時代的進步,spring也在不斷完善,直到今天,springboot的問世和流行,導致springsecurity的整合和理解也變得越來越簡單,這主要還要歸功於sopringboot開發人員做出的努力。在原有的springsecurity的基礎上,springboot團隊專門爲其包裝了springboot的起步依賴,使得springsercurity的整合難度急劇下降,即便是新手也能夠很容易使用。
spring boot security 與spring security的關係
在spring security框架中,主要包含了兩個依賴jar,分別是spring-security-web和spring-security-config依賴,分別如下:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
spring boot對上面兩個jar包進行了封裝,僅僅只是封裝,並沒有改動spring security兩個包的內容,並且加上了spring boot的起步依賴的特性,聚合成了spring-boot-starter-security這個起步依賴包,如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
整合步驟
上面說完了spring boot和spring security的關係後,簡要的來敘述一下spring security的整合步驟。整個流程其實非常簡單。
第一步:
構建一個spring boot工程,這個利用idea的Spring Initializr很容易就構建了
第二步:
引入spring boot爲spring security的包裝的起步依賴,也就是上面提到的spring-boot-starter-security,pom文件如下(整個pom文件都列出):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
後端控制器代碼:
package controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@RequestMapping("/")
public String root(){
return "redirect:/index";
}
@RequestMapping("/index")
public String index(){
return "index";
}
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/user/index")
public String userIndex(){
return "/user/index";
}
@RequestMapping("/login-error")
public String loginError(Model model){
model.addAttribute("loginError",true);
return "login";
}
@RequestMapping("/401")
public String accessDenied(){
return "401";
}
}
後端的配置大致完成了,接下來爲了演示清楚一些,編寫一些簡單的頁面。
編寫相關頁面
我們使用了thymeleaf引擎,寫一些html5頁面,注意,thymeleaf也需要在application.yml進行配置。配置文件如下:
spring:
thymeleaf:
mode: HTML5
encoding: UTF-8
cache: false
登陸頁面(login/html):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Login page</h1>
<p>User 角色用戶:forezp/123456</p>
<p>Admin 角色用戶:admin/123456</p>
<p th:if="${loginError}" class="error">用戶名與密碼錯誤</p>
<form th:action="@{/login}" method="post">
<label for="username">用戶名</label>
<input type="text" id="username" name="username" autofocus="autofocus">
<br />
<label for="password"> 密碼</label>
<input type="password" id="password" name="password">
<br />
<input type="submit" value="登錄">
</form>
<p><a href="/index" th:href="@{/index}"> 返回首頁</a></p>
</body>
</html>
首頁(index.html):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>Hello spring security</title>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}" />
</head>
<body>
<h1>Hello spring security</h1>
<p>這個界面沒有受到保護,你可以進入已被保護的界面</p>
<div th:fragment="logout" sec:authorize="isAuthorize()">
登錄用戶:<span sec:authentication="name"></span> |
用戶角色:<span sec:authentication="principal.authorities"></span>
<div>
<form action="#" th:action="@{/logout}" method="post">
<input type="submit" value="登出">
</form>
</div>
</div>
<ul>
<li>點擊<a href="/user/index" th:href="@{/user/index}">去/user/index已被保護的界面</a></li>
</ul>
</body>
</html>
權限不夠顯示的頁面(401.html):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<body>
<div>
<dev>
<h2>權限不夠</h2>
</dev>
</div>
<div sec:authorize="isAuthenticated()">
<p>已有用戶登錄</p>
<p>用戶:<span sec:authentication="name"></sapn></p>
<p>角色:<span sec:authentication="principal.authorities"></span></p>
</div>
<div sec:authentication="isAnonymous()">
<p>未有用戶登錄</p>
</div>
<p>
拒絕訪問
</p>
</body>
</html>
用戶首頁(user/index.html),該資源被springsecurity保護,只擁有“USER”角色的用戶才能夠訪問,其代碼如下:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello spring security</title>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}"/>
</head>
<body>
<div th:substituteby="index::logout"></div>
<h1>這個是被保護的界面</h1>
<p><a href="/index" th:href="@{/index}">返回首頁</a></p>
<p><a href="/index" th:href="@{/blogs}">管理博客</a></p>
</body>
</html>