文章目錄
- 前言
- 一、為什么使用SpringSecurity
- 一、關于SpringSecurity
- 匯入模板素材
- 定制首頁
前言
筆記整理來源于狂神視頻https://www.bilibili.com/video/BV1PE411i7CV
主要包含SpringSecurity簡介以及快速上手
一、為什么使用SpringSecurity
在web開發中,安全占據第一位置
我們可以通過一些簡單的安全策略,例如過濾器,攔截器保證安全
安全是一個非功能性需求,做網站,后臺應該在設計之初進行考慮,在我們設計之前
就應該把這些東西考慮進去,雖然我們可以通過攔截器,過濾器來完成需求,但是會有大量的原生代碼,冗余
,而通過SpringSecurity,我們只需要進行簡單的呼叫,便可實作無數復雜的功能
專案中所涉及的安全性問題
- 功能權限
- 訪問權限
- 選單權限
市面上比較知名的安全的框架
- shiro
- SpringSecurity
這兩個框架除了類不一樣,名字不一樣,其他地方有很多相似之處,我們此次便去了解SpringSecurity
一、關于SpringSecurity
參考檔案:
https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/htmlsingle
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
Spring security 是一個功能強大且高度可定制的身份驗證和訪問控制框架,它是保護基于 spring 的應用程式的事實上的標準,spring security 是一個框架,專注于為 java應用程式提供身份驗證和授權,就像所有的spring專案一樣,spring安全性的真正威力在于它可以很容易地擴展以滿足客戶需求
Spring Security是針對Spring專案的安全框架,也是Spring Boot底層安全模板默認的技術選型,他可以實作強大的Web安全控制,對于安全控制,我們僅需要引入spring-boot-starter-security模塊,進行少量的配置,即可實作強大的安全管理
需要牢記的幾個類
WebSecurityConfigurerAdapter: 自定義Security策略
AuthenticationManagerBuilder: 自定義認證策略
@EnableWebSecurity: 開啟WebSecurity模式
“認證”(Authentication)
“授權”(Authorization)
這些概念是通用的,而不是只在Spring Security中存在
匯入模板素材

首頁index.html:

RouterControler跳往各個頁面
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RouterControler {
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
//跳往等級頁面
@RequestMapping("/level1/{id}")
public String toLevel1(@PathVariable("id") int id){
return "views/level1/"+id;
}
//跳往等級頁面
@RequestMapping("/level2/{id}")
public String toLevel2(@PathVariable("id") int id){
return "views/level2/"+id;
}
//跳往等級頁面
@RequestMapping("/level3/{id}")
public String toLevel3(@PathVariable("id") int id){
return "views/level3/"+id;
}
}
SecurityConfig配置SpringSecurity:
package com.kuang.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//AOP思想
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//鏈式編程
//http安全策略
//授權
@Override
protected void configure(HttpSecurity http) throws Exception {
//首頁所有人可訪問,功能頁只有對應有權限的人才能訪問
//請求授權的規則
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//沒有權限默認跳轉至登錄頁
http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login").defaultSuccessUrl("/index");
//開啟注銷功能,跳轉回登錄頁
http.logout().logoutSuccessUrl("/toLogin");
http.csrf().disable();
//開啟記住密碼功能
http.rememberMe().rememberMeParameter("remember");
}
//認證,springboot 2.1.X可以直接使用
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//這些資料正常從資料庫中獲得
//下面是從記憶體中取得
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("zs").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2","vip3")
.and()
.withUser("ls").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123")).roles("vip1")
;
}
}
配置完成進入網頁,點擊vip2自動跳轉至登錄頁

此時輸入資料進行登錄,發現報錯

這是因為我們允許通過的密碼沒有經過加密,不安全,被Spring Security駁回
Spring Security5.0+ 新增了很多加密辦法

這里我們采用BCryptPasswordEncoder方式的加密
//認證,springboot 2.1.X可以直接使用
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//這些資料正常從資料庫中獲得
//下面是從記憶體中取得
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("zs").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2","vip3")
.and()
.withUser("ls").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123")).roles("vip1")
;
}
進行登錄跳轉:

跳轉成功
那么接下來,如果我們以游客guest身份登錄,登錄之后只想讓他看到頁面的部分功能應該怎么辦呢?這個時候需要通過Thymeleaf加SpringSecurity來實作
匯入入Thymeleaf加SpringSecurity整合包:
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
在頁面引入命名空間:
xmlns:th="http://www.thymeleaf.org" xmlns:sec=http://www.thymeleaf.org/extras/spring-security
在html利用sec:authorize="hasRole(‘xxx’)"對權限進行篩選
index頁面代碼:
<!--主容器-->
<div class="ui container">
<div class="ui segment" id="index-header-nav" th:fragment="nav-menu">
<div class="ui secondary menu">
<a class="item" th:href="@{/index}">首頁</a>
<!--登錄注銷-->
<div class="right menu">
<!--未登錄顯示登錄按鈕-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登錄
</a>
</div>
<!--如果已登錄,顯示用戶名,注銷-->
<div sec:authorize="isAuthenticated()">
<a class="item">
用戶名:<span sec:authentication="name"></span>
vip等級:<span sec:authentication="principal.authorities"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注銷
</a>
</div>
</div>
</div>
</div>
<div class="ui segment" style="text-align: center">
<h3>Spring Security</h3>
</div>
<div>
<br>
<div class="ui three column stackable grid">
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip2')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 2</h5>
<hr>
<div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
<div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
<div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip3')">
<div class="ui raised segment">
<div class="ui">
<div class="content" >
<h5 class="content">Level 3</h5>
<hr>
<div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
<div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
<div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
我們為zs賦予的權限為vip3,zs進行登錄所看到的畫面

我們為ls賦予的權限為vip2,ls進行登錄所看到的畫面:

開啟記住密碼功能:
http.rememberMe();

點擊Remember me on this computer,用zs賬戶登錄之后關閉瀏覽器,再次打開發現

賬戶資訊依舊存在
我們查看記憶體中的cookie:

我們發現security自動創建了remember-me的cookie物件,且有效期為14天
定制首頁
**在原始碼中我們發現:
* /**@Override
* protected void configure(HttpSecurity http) throws Exception {
*
* http.authorizeRequests().antMatchers("").hasRole("USER").and().formLogin()
* .usernameParameter("username") // default is username
* .passwordParameter("password") // default is password
* .loginPage("/authentication/login") // default is /login with an HTTP get
* .failureUrl("/authentication/login?failed") // default is /login?error
* .loginProcessingUrl("/authentication/login/process"); // default is /login
* // with an HTTP
* // post
* }**
我們可以通過loginPage可以設定登錄頁,通過failureUrl設定失敗的登錄頁
由此我們可以設定自己的登錄頁
http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login").defaultSuccessUrl("/index");
這里loginProcessingUrl()相當于一個中轉站,前臺界面提交表單之后跳轉到這個路徑進行User DetailsService的驗證,如果成功, defaultSuccessUrl()如果失敗,那么轉向failureUrl("/error.html")
**最終樣式:**

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/281198.html
標籤:其他
上一篇:介紹一位超級大美女
下一篇:撿到了一枚鳥蛋!
