(一)概述
Spring Security是一個功能強大且高度可自訂的身份驗證和存取控制框架,Spring Security主要做兩個事情,認證、授權。我之前寫過一篇關於SpringSecurity的博客,但是當時只是介紹了基於mock數據的案例,本期就來介紹一下基於真實數據的認證授權實現。
(二)前期專案搭建
為了更好的展示SpringSecurity,我們先建造一個簡單的web專案出來。引入thymeleaf依賴
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-thymeleaf</artifactid> </dependency> <dependency> <groupid>org.thymeleaf</groupid> <artifactid>thymeleaf-spring5</artifactid> </dependency> <dependency> <groupid>org.thymeleaf.extras</groupid> <artifactid>thymeleaf-extras-java8time</artifactid> </dependency>
新建一個登陸頁,一個首頁,然後幾個不同等級的展示頁面: login.html
nbsp;html> <meta> <title>登陆页</title> <div> <form> <h3 id="登陆页">登陆页</h3> <input> <input> <button>登陆</button> </form> </div>
index.html
nbsp;html> <meta> <title>首页</title> <div> <h3 id="首页">首页</h3> <a>登陆</a> <div> <div> <h4 id="level">level1</h4> <a>level-1-1</a> <hr> <a>level-1-2</a> </div> <div> <h4 id="level">level2</h4> <a>level-2-1</a> <hr> <a>level-2-2</a> </div> <div> <h4 id="level">level3</h4> <a>level-3-1</a> <hr> <a>level-3-2</a> </div> </div> </div>
另外還有幾個不同等級的頁面
分別在body中寫上自己對應的編號。
nbsp;html> <meta> <title>Title</title> level-1-1
最後寫一個controller來接收請求:
@Controller public class RouteController { @RequestMapping({"/","/index"}) public String index(){ return "index"; } @RequestMapping("/login") public String toLogin(){ return "login"; } @RequestMapping("/level1/{id}") public String level1(@PathVariable("id")String id){ return "level1/"+id; } @RequestMapping("/level2/{id}") public String level2(@PathVariable("id")String id){ return "level2/"+id; } @RequestMapping("/level3/{id}") public String level3(@PathVariable("id")String id){ return "level3/"+id; } }
最終的效果如下:
最終實作等級不同的level頁面根據不同權限進行跳轉。
後台基於Mybatis和Mysql資料庫實現,因此我們除了引入SpringSecurity的依賴之外,還需要引入Mybatis相關依賴:
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-security</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-jdbc</artifactid> </dependency> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <scope>runtime</scope> </dependency> <dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>2.1.3</version> </dependency>
在設定文件中新增資料來源相關信息,以及Mybatis的配置:
spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml
(三)認證與授權的實現
3.1 表結構設計
認證和授權在表設計上應該分在兩個表內,一個表存儲用戶信息包括密碼等,另一個表存儲授權信息,還需要一個表建立用戶和授權之間的關聯,給出最終的表結構:
CREATE TABLE `roles` ( `id` int(4) NOT NULL, `rolename` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `sysuser` ( `id` int(4) NOT NULL, `username` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `user_role` ( `id` int(4) NOT NULL, `user_id` int(4) DEFAULT NULL, `role_id` int(4) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
接下來是針對這三張表的實體類,Mapper介面以及xml文件,你可以不看程式碼,主要實作一個透過使用者名稱來尋找使用者以及相關權限的操作:
@Data public class Roles { private Integer id; private String roleName; } @Data public class SysUser { private Integer id; private String userName; private String password; private List<roles> roles; }</roles>
Mapper介面:
public interface UserMapper { public SysUser getUserByUserName(@Param("userName") String userName); }
xml實作:
<?xml version="1.0" encoding="UTF-8" ?> nbsp;mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper> <resultmap> <id></id> <result></result> <result></result> <collection> <result></result> </collection> </resultmap> <select> select sysuser.*,roles.rolename from sysuser LEFT JOIN user_role on sysuser.id= user_role.user_id LEFT JOIN roles on user_role.role_id=roles.id where username= #{userName} </select> </mapper>
3.2 認證過程
SpringSecurity的認證過程是這樣的,首先透過用戶名或其他唯一的ID在資料庫裡找到這個用戶,用戶的密碼以非對稱加密的方式儲存。取到用戶後將前台傳入的密碼加密後和資料庫中已經加密好的欄位進行對比,從而通過認證。
上面這個過程中的第一步透過使用者名稱找到使用者的操作需要透過Service服務來實現,而這個Service服務需要繼承SpringSecurity中的UserDetailsService介面。這個介面回傳一個SpringSecurity的User物件。
@Service public class UserService implements UserDetailsService { @Resource private UserMapper userMapper; //根据用户名找到对应的用户信息 @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { SysUser sysUser = userMapper.getUserByUserName(s); if (sysUser!=null){ List<grantedauthority> roles=new ArrayList(); sysUser.getRoles().stream().forEach(x->{ roles.add(new SimpleGrantedAuthority(x.getRoleName())); }); return new User(sysUser.getUserName(),sysUser.getPassword(),roles); } throw new UsernameNotFoundException("用户未找到"); } }</grantedauthority>
3.3 Security攔截設定
上面的步驟都完成後就開始設定Security了,寫一個設定方法SecurityConfig,程式碼層面很簡單,認證傳入userService對象,會自動把資料庫中取出的密碼和前端傳過來的密碼進行對照。同時在userService中也傳入了roles集合,在授權處為不同的頁面附上不同的權限即可。
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; //授权 @Override protected void configure(HttpSecurity http) throws Exception { //首页所有人都能访问,level页面只有有权限的人才能访问 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); //没有权限默认跳到登陆页,默认会重定向到/login http.formLogin(); } //认证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder()); } }
3.4 其他注意點
我在認證的時候使用的密碼加密方式是BCryptPasswordEncoder,因此存入資料庫中的密碼也需要被加密,常用的方式就是在註冊時通過同樣的方式將密碼加密存入資料庫:
String password="xxx"; BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String encode=bCryptPasswordEncoder.encode(password);
以上是如何用SpringBoot+SpringSecurity實現基於真實資料的授權認證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

Java的平台獨立性是指編寫的代碼可以在任何安裝了JVM的平台上運行,無需修改。 1)Java源代碼編譯成字節碼,2)字節碼由JVM解釋執行,3)JVM提供內存管理和垃圾回收功能,確保程序在不同操作系統上運行。

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算显著提升了Java的平台独立性。1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3漢化版
中文版,非常好用