java每日精進1.31(SpringSecurity)

在所有的開發的系統中,都必須做認證(authentication)和授權(authorization),以保證系統的安全性。

一、基礎使用

1.依賴

<dependencies><!-- 實現對 Spring MVC 的自動化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 實現對 Spring Security 的自動化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies>

2.application.yml

spring:# Spring Security 配置項,對應 SecurityProperties 配置類security:# 配置默認的 InMemoryUserDetailsManager 的用戶賬號與密碼。user:name: user # 賬號password: user # 密碼roles: ADMIN # 擁有角色

3.Controller

@RestController
@RequestMapping("/admin")
public class AdminController {@GetMapping("/demo")public String demo() {return "success!";}}

項目啟動成功后,瀏覽器訪問?http://127.0.0.1:8080/admin/demo?接口。因為未登錄,所以被 Spring Security 攔截到登錄界面。

因為我們沒有自定義登錄界面,所以默認會使用??DefaultLoginPageGeneratingFilter??類,生成上述界面。

登錄完成后,因為 Spring Security 會記錄被攔截的訪問地址,所以瀏覽器自動動跳轉返回界面;

二、自定義規則(自定義 Spring Security 的配置,實現權限控制。)

1.SecurityConfig

創建 SecurityConfig 配置類,繼承 WebSecurityConfigurerAdapter 抽象類,實現 Spring Security 在 Web 場景下的自定義配置。代碼如下:

// SecurityConfig.java@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {// ...}

重寫 #configure(AuthenticationManagerBuilder auth) 方法,實現 AuthenticationManager 認證管理器。

// SecurityConfig.java@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.//使用內存中的 InMemoryUserDetailsManagerinMemoryAuthentication()//不使用 PasswordEncoder 密碼編碼器.passwordEncoder(NoOpPasswordEncoder.getInstance())//  配置 admin 用戶.withUser("admin").password("admin").roles("ADMIN")// 配置 normal 用戶.and().withUser("normal").password("normal").roles("NORMAL");
}

重寫?#configure(HttpSecurity http)?方法,主要配置 URL 的權限控制。代碼如下:

// SecurityConfig.java@Override
protected void configure(HttpSecurity http) throws Exception {http// <X> 配置請求地址的權限.authorizeRequests().antMatchers("/test/echo").permitAll() // 所有用戶可訪問.antMatchers("/test/admin").hasRole("ADMIN") // 需要 ADMIN 角色.antMatchers("/test/normal").access("hasRole('ROLE_NORMAL')") // 需要 NORMAL 角色。// 任何請求,訪問的用戶都需要經過認證.anyRequest().authenticated().and()// <Y> 設置 Form 表單登錄.formLogin()
//                    .loginPage("/login") // 登錄 URL 地址.permitAll() // 所有用戶可訪問.and()// 配置退出相關.logout()
//                    .logoutUrl("/logout") // 退出 URL 地址.permitAll(); // 所有用戶可訪問
}

調用?HttpSecurity#authorizeRequests()?方法,開始配置 URL 的權限控制。注意看艿艿配置的四個權限控制的配置。下面,是配置權限控制會使用到的方法:

  • #(String... antPatterns)?方法,配置匹配的 URL 地址,可傳入多個。
  • 【常用】#permitAll()?方法,所有用戶可訪問。
  • 【常用】#denyAll()?方法,所有用戶不可訪問。
  • 【常用】#authenticated()?方法,登錄用戶可訪問。
  • #anonymous()?方法,無需登錄,即匿名用戶可訪問。
  • #rememberMe()?方法,通過remember me??登錄的用戶可訪問。
  • #fullyAuthenticated()?方法,非remember me?登錄的用戶可訪問。
  • #hasIpAddress(String ipaddressExpression)?方法,來自指定 IP 表達式的用戶可訪問。
  • 【常用】#hasRole(String role)?方法, 擁有指定角色的用戶可訪問。
  • 【常用】#hasAnyRole(String... roles)?方法,擁有指定任一角色的用戶可訪問。
  • 【常用】#hasAuthority(String authority)?方法,擁有指定權限(authority)的用戶可訪問。
  • 【常用】#hasAuthority(String... authorities)?方法,擁有指定任一權限(authority)的用戶可訪問。
  • 【最牛】#access(String attribute)?方法,執行結果為?true?時,可以訪問。

2.Controller

@RestController
@RequestMapping("/test")
public class TestController {@GetMapping("/echo")public String demo() {return "示例返回";}@GetMapping("/home")public String home() {return "我是首頁";}@GetMapping("/admin")public String admin() {return "我是管理員";}@GetMapping("/normal")public String normal() {return "我是普通用戶";}}
  • 對于?/test/echo?接口,直接訪問,無需登錄。
  • 對于?/test/home?接口,無法直接訪問,需要進行登錄。
  • 對于?/test/admin?接口,需要登錄「admin/admin」用戶,因為需要 ADMIN 角色。
  • 對于?/test/normal?接口,需要登錄「normal/normal」用戶,因為需要 NORMAL 角色。

3.Spring Security 的注解,實現權限控制

1.修改權限配置類?

修該 security config?配置類,增加?@EnableGlobalMethodSecurity?注解,開啟對 Spring Security 注解的方法,進行權限驗證。代碼如下:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter

然后即可添加方法級別的權限驗證

@PreAuthorize("hasRole('ROLE_NORMAL')")@GetMapping("/normal")public String normal() {return "我是普通用戶";}

三、Spring Session

Session 的一致性,簡單來理解,就是相同 sessionid 在多個 Web 容器下,Session 的數據要一致。

我們先以用戶使用瀏覽器,Web 服務器為單臺?TomcatA 舉例子。

  • 瀏覽器在第一次訪問 Web 服務器 TomcatA 時,TomcatA 會發現請求的 Cookie 中存在 sessionid ,所以創建一個 sessionid 為 X 的 Session ,同時將該 sessionid 寫回給瀏覽器的 Cookie 中。
  • 瀏覽器在下一次訪問 Web 服務器 TomcatA 時,TomcatA 會發現請求的 Cookie 中存在 sessionid 為 X ,則直接獲得 X 對應的 Session 。

但是如果情況如下:

  • 瀏覽器訪問 TomcatA ,獲得 sessionid 為 X 。同時,在多臺 Tomcat 的情況下,我們需要采用 Nginx 做負載均衡。
  • 瀏覽器又發起一次請求訪問 Web 服務器,Nginx 負載均衡轉發請求到 TomcatB 上。TomcatB 會發現請求的 Cookie 中存在 sessionid 為 X ,則直接獲得 X 對應的 Session 。結果呢,找不到 X 對應的 Session ,只好創建一個 sessionid 為 X 的 Session 。
  • 此時,雖然說瀏覽器的 sessionid 是 X ,但是對應到兩個 Tomcat 中兩個 Session 。那么,如果在 TomcatA 上做的 Session 修改,TomcatB 的 Session 還是原樣,這樣就會出現?Session 不一致的問題。

三種解決方案:

第一種,Session 黏連

使用 Nginx 實現會話黏連,將相同 sessionid 的瀏覽器所發起的請求,轉發到同一臺服務器。這樣,就不會存在多個 Web 服務器創建多個 Session 的情況,也就不會發生 Session 不一致的問題。

不過,這種方式目前基本不被采用。因為,如果一臺服務器重啟,那么會導致轉發到這個服務器上的 Session 全部丟失。

第二種,Session 復制

Web 服務器之間,進行 Session 復制同步。僅僅適用于實現 Session 復制的 Web 容器,例如說 Tomcat 、Weblogic 等等。

不過,這種方式目前基本也不被采用。試想一下,如果我們有 5 臺 Web 服務器,所有的 Session 都要同步到每一個節點上,一個是效率低,一個是浪費內存。

第三種,Session 外部化存儲

不同于上述的兩種方案,Session 外部化存儲,考慮不再采用 Web 容器的內存中存儲 Session ,而是將 Session 存儲外部化,持久化到 MySQL、Redis、MongoDB 等等數據庫中。這樣,Tomcat 就可以無狀態化,專注提供 Web 服務或者 API 接口,未來拓展擴容也變得更加容易。

而實現 Session 外部化存儲也有兩種方式:

① 基于 Tomcat、Jetty 等 Web 容器自帶的拓展,使用讀取外部存儲器的 Session 管理器。例如說:tomcat 使用 Redis 存儲 Session 、實現 Jetty 使用 MySQL、MongoDB 存儲 Session 。

② 基于應用層封裝 HttpServletRequest?請求對象,包裝成自己的 RequestWrapper 對象,從而讓實現調用 HttpServletRequest#getSession() 方法時,獲得讀寫外部存儲器的 SessionWrapper 對象。

依賴:

<dependencies><!-- 實現對 Spring MVC 的自動化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 實現對 Spring Session 使用 Redis 作為數據源的自動化配置 --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency><!-- 實現對 Spring Data Redis 的自動化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><!-- 去掉對 Lettuce 的依賴,因為 Spring Boot 優先使用 Lettuce 作為 Redis 客戶端 --><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><!-- 引入 Jedis 的依賴,這樣 Spring Boot 實現對 Jedis 的自動化配置 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!-- 實現對 Spring Security 的自動化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies>

配置文件:

spring:# 對應 RedisProperties 類redis:host: 127.0.0.1port: 6379password: # Redis 服務器密碼,默認為空。生產中,一定要設置 Redis 密碼!database: 0 # Redis 數據庫號,默認為 0 。timeout: 0 # Redis 連接超時時間,單位:毫秒。# 對應 RedisProperties.Jedis 內部類jedis:pool:max-active: 8 # 連接池最大連接數,默認為 8 。使用負數表示沒有限制。max-idle: 8 # 默認連接數最大空閑的連接數,默認為 8 。使用負數表示沒有限制。min-idle: 0 # 默認連接池最小空閑的連接數,默認為 0 。允許設置 0 和 正數。max-wait: -1 # 連接池最大阻塞等待時間,單位:毫秒。默認為 -1 ,表示不限制。# 對應 SecurityProperties 類security:user: # 配置內存中,可登錄的用戶名和密碼name: nihaopassword: nihao

SessionConfiguration:

@Configuration
@EnableRedisHttpSession // 自動化配置 Spring Session 使用 Redis 作為數據源
public class SessionConfiguration {}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67694.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67694.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67694.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單的SQL語句的快速復習

語法的執行順序 select 4 字段列表 from 1 表名列表 where 2 條件列表 group by 3 分組前過濾 having 分組后過濾 order by 5 排序字段列表 limit 6 分頁參數 聚合函數 count 統計數量 max 最大值 min 最小值 avg 平均 sum 總和 分組查詢使…

《程序人生》工作2年感悟

一些雜七雜八的感悟&#xff1a; 1.把事做好比什么都重要&#xff0c; 先樹立量良好的形象&#xff0c;再橫向發展。 2.職場就是人情世故&#xff0c;但也不要被人情世故綁架。 3.要常懷感恩的心&#xff0c;要記住幫助過你的人&#xff0c;愿意和你分享的人&#xff0c;有能力…

17.2 圖形繪制8

版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請在顯著位置標明本文出處以及作者網名&#xff0c;未經作者允許不得用于商業目的。 17.2.10 重繪 先看以下例子&#xff1a; 【例 17.28】【項目&#xff1a;code17-028】繪制填充矩形。 private void button1_Clic…

自定義數據集 使用pytorch框架實現邏輯回歸并保存模型,然后保存模型后再加載模型進行預測,對預測結果計算精確度和召回率及F1分數

import numpy as np import torch import torch.nn as nn import torch.optim as optim from sklearn.metrics import precision_score, recall_score, f1_score# 數據準備 class1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4,…

neo4j入門

文章目錄 neo4j版本說明部署安裝Mac部署docker部署 neo4j web工具使用數據結構圖數據庫VS關系數據庫 neo4j neo4j官網Neo4j是用ava實現的開源NoSQL圖數據庫。Neo4作為圖數據庫中的代表產品&#xff0c;已經在眾多的行業項目中進行了應用&#xff0c;如&#xff1a;網絡管理&am…

腳本運行禁止:npm 無法加載文件,因為在此系統上禁止運行腳本

問題與處理策略 1、問題描述 npm install -D tailwindcss執行上述指令&#xff0c;報如下錯誤 npm : 無法加載文件 D:\nodejs\npm.ps1&#xff0c;因為在此系統上禁止運行腳本。 有關詳細信息&#xff0c;請參閱 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_…

Java基礎——分層解耦——IOC和DI入門

目錄 三層架構 Controller Service Dao ?編輯 調用過程 面向接口編程 分層解耦 耦合 內聚 軟件設計原則 控制反轉 依賴注入 Bean對象 如何將類產生的對象交給IOC容器管理&#xff1f; 容器怎樣才能提供依賴的bean對象呢&#xff1f; 三層架構 Controller 控制…

智慧園區系統集成解決方案引領未來城市管理的智能化轉型

內容概要 在現代城市管理的背景下&#xff0c;“智慧園區系統集成解決方案”正扮演著越來越重要的角色。這種解決方案不僅僅是技術上的創新&#xff0c;更是一種全新的管理理念&#xff0c;它旨在通過高效的數據整合與分析&#xff0c;優化資源配置&#xff0c;提升運營效率。…

99.24 金融難點通俗解釋:MLF(中期借貸便利)vs LPR(貸款市場報價利率)

目錄 0. 承前1. 什么是MLF&#xff1f;1.1 專業解釋1.2 通俗解釋1.3 MLF的三個關鍵點&#xff1a; 2. 什么是LPR&#xff1f;2.1 專業解釋2.2 通俗解釋2.3 LPR的三個關鍵點&#xff1a; 3. MLF和LPR的關系4. 傳導機制4.1 第一步&#xff1a;央行調整MLF4.2 第二步&#xff1a;銀…

【VM】VirtualBox安裝CentOS8虛擬機

閱讀本文前&#xff0c;請先根據 VirtualBox軟件安裝教程 安裝VirtualBox虛擬機軟件。 1. 下載centos8系統iso鏡像 可以去兩個地方下載&#xff0c;推薦跟隨本文的操作用阿里云的鏡像 centos官網&#xff1a;https://www.centos.org/download/阿里云鏡像&#xff1a;http://…

Elasticsearch中的度量聚合:深度解析與實戰應用

在大數據和實時分析日益重要的今天&#xff0c;Elasticsearch以其強大的搜索和聚合能力&#xff0c;成為了眾多企業和開發者進行數據分析和處理的首選工具。本文將深入探討Elasticsearch中的度量聚合&#xff08;Metric Aggregations&#xff09;&#xff0c;展示其如何在數據分…

C_C++輸入輸出(下)

C_C輸入輸出&#xff08;下&#xff09; 用兩次循環的問題&#xff1a; 1.一次循環決定打印幾行&#xff0c;一次循環決定打印幾項 cin是>> cout是<< 字典序是根據字符在字母表中的順序來比較和排列字符串的&#xff08;字典序的大小就是字符串的大小&#xff09;…

電腦要使用cuda需要進行什么配置

在電腦上使用CUDA&#xff08;NVIDIA的并行計算平臺和API&#xff09;&#xff0c;需要進行以下配置和準備&#xff1a; 1. 檢查NVIDIA顯卡支持 確保你的電腦擁有支持CUDA的NVIDIA顯卡。 可以在NVIDIA官方CUDA支持顯卡列表中查看顯卡型號是否支持CUDA。 2. 安裝NVIDIA顯卡驅動…

深入解析:一個簡單的浮動布局 HTML 示例

深入解析&#xff1a;一個簡單的浮動布局 HTML 示例 示例代碼解析代碼結構分析1. HTML 結構2. CSS 樣式 核心功能解析1. 浮動布局&#xff08;Float&#xff09;2. 清除浮動&#xff08;Clear&#xff09;3. 其他樣式 效果展示代碼優化與擴展總結 在網頁設計中&#xff0c;浮動…

家居EDI:Hom Furniture EDI需求分析

HOM Furniture 是一家成立于1977年的美國家具零售商&#xff0c;總部位于明尼蘇達州。公司致力于提供高品質、時尚的家具和家居用品&#xff0c;滿足各種家庭和辦公需求。HOM Furniture 以廣泛的產品線和優質的客戶服務在市場上贏得了良好的口碑。公司經營的產品包括臥室、客廳…

【VUE案例練習】前端vue2+element-ui,后端nodo+express實現‘‘文件上傳/刪除‘‘功能

近期在做跟畢業設計相關的數據后臺管理系統&#xff0c;其中的列表項展示有圖片展示&#xff0c;添加/編輯功能有文件上傳。 “文件上傳/刪除”也是我們平時開發會遇到的一個功能&#xff0c;這里分享個人的實現過程&#xff0c;與大家交流談論~ 一、準備工作 本次案例使用的…

C++中的析構器(Destructor)(也稱為析構函數)

在C中&#xff0c;析構器&#xff08;Destructor&#xff09;也稱為析構函數&#xff0c;它是一種特殊的成員函數&#xff0c;用于在對象銷毀時進行資源清理工作。以下是關于C析構器的詳細介紹&#xff1a; 析構函數的特點 名稱與類名相同&#xff0c;但前面有一個波浪號 ~&a…

VLN視覺語言導航基礎

0 概述 視覺語言導航模型旨在構建導航決策模型 π π π&#xff0c;在 t t t時刻&#xff0c;模型能夠根據指令 W W W、歷史軌跡 τ { V 1 , V 2 , . . . , V t ? 1 } \tau\{V_1,V_2,...,V_{t-1}\} τ{V1?,V2?,...,Vt?1?}和當前觀察 V t { P t , R t , N ( V t ) } V_…

AI協助探索AI新構型的自動化創新概念

訓練AI自生成輸出模塊化代碼&#xff0c;生成元代碼級別的AI功能單元代碼&#xff0c;然后再由AI組織為另一個AI&#xff0c;實現AI開發AI的能力&#xff1b;用AI協助探索迭代新構型AI將會出現&#xff0c;并成為一種新的技術路線潮流。 有限結點&#xff0c;無限的連接形式&a…

Flux的三步煉丹爐——fluxgym(三):矩陣測試

前面兩篇文章給大家介紹了如何準備素材和怎么煉丹&#xff0c;現在我們拿到訓練完成后的多個Lora怎么才能確定哪個才是我們需要的、效果最好的呢&#xff1f;答案就是使用xyz圖表測試&#xff0c;也稱為矩陣測試&#xff0c;通過控制控制變量的方法對Lora模型批量生圖&#xff…