最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot配置Spring?Security的實(shí)現(xiàn)示例

 更新時間:2024年10月24日 08:40:29   作者:G皮T  
本文主要介紹了SpringBoot配置Spring?Security的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1.繼承 WebSecurityConfigurerAdapter

通過重寫抽象接口 WebSecurityConfigurerAdapter,再加上注解 @EnableWebSecurity,可以實(shí)現(xiàn) Web 的安全配置。

WebSecurityConfigurerAdapterConfig 模塊一共有 3 個 builder(構(gòu)造程序)。

  • AuthenticationManagerBuilder:認(rèn)證相關(guān) builder,用來配置全局的認(rèn)證相關(guān)的信息。它包含 AuthenticationProvider 和 UserDetailsService,前者是 認(rèn)證服務(wù)提供者,后者是 用戶詳情查詢服務(wù)。
  • WebSecurity:進(jìn)行全局請求忽略規(guī)則配置、HttpFirewall 配置、debug 配置、全局 SecurityFilterChain 配置。
  • HttpSecurity:進(jìn)行權(quán)限控制規(guī)則相關(guān)配置。

配置安全,通常要重寫以下方法:

// 通過 auth 對象的方法添加身份驗(yàn)證
protected void configure(AuthenticationManagerBuilder auth) throws Exception {}
// 通常用于設(shè)置忽略權(quán)限的靜態(tài)資源
public void configure(WebSecurity web) throws Exception {}
// 通過 HTTP 對象的 authorizeRequests() 方法定義 URL 訪問權(quán)限。默認(rèn)為 formLogin() 提供一個簡單的登錄驗(yàn)證頁面
protected void configure(HttpSecurity httpSecurity) throws Exception {}

2.配置自定義策略

配置安全需要繼承 WebSecurityConfigurerAdapter,然后重寫其方法,見以下代碼:

package com.example.demo.config;
 
// 指定為配置類
@Configuration
// 指定為 Spring Security 配置類,如果是 WebFlux,則需要啟用@EnableWebFluxSecurity 
@EnableWebSecurity
// 如果要啟用方法安全設(shè)置,則開啟此項(xiàng)。
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  public void configure(WebSecurity web) throws Exception {
    //不攔截靜態(tài)資源
    web.ignoring().antMatchers("/static/**");
  }
  
  @Bean
  public PasswordEncoder passwordEncoder() {
    // 使用 BCrypt 加密
    return new BCryptPasswordEncoder();
  }
  
  @Override
  protected void configure(HttpSecurity http) throws Exception { 
  	http.formLogin()
  			.usernameParameter("uname").passwordParameter("pwd").loginPage("/admin/login").permitAll()
				.and()
			.authorizeRequests()
				.antMatchers("/admin/**").hasRole("ADMIN")
				// 除上面外的所有請求全部需要鑒權(quán)認(rèn)證
				.anyRequest().authenticated();
    http.logout().permitAll();
    http.rememberMe().rememberMeParameter("rememberme");
    // 處理異常,拒絕訪問就重定向到 403 頁面 
    http.exceptionHandling().accessDeniedPage("/403");
    http.logout().logoutSuccessUrl("/");
    http.csrf().ignoringAntMatchers("/admin/upload");
  }
}
  • formLogin():自定義用戶登錄驗(yàn)證的頁面。表示開啟表單登錄配置,loginPage 用來配置登錄頁面地址;usernameParameter 表示登錄用戶名的參數(shù)名稱;passwordParameter 表示登錄密碼的參數(shù)名稱;permitAll 表示跟登錄相關(guān)的頁面和接口不做攔截,直接通過。需要注意的是 usernameParameter、passwordParameter 需要和 login.html 中登錄表單的配置一致。
  • authorizeRequests():定義哪些 URL 需要被保護(hù),哪些不需要被保護(hù)。
  • antMatchers("/admin/**").hasRole("ADMIN"):定義 /admin/ 下的所有 URL。只有擁有 ADMIN 角色的用戶才有訪問權(quán)限。
  • .logout().permitAll():表示在 Spring Security 配置中,‌無論用戶是否經(jīng)過身份驗(yàn)證,‌都可以訪問注銷(‌logout)‌頁面。‌這意味著,‌即使是一個未經(jīng)過身份驗(yàn)證的用戶也可以訪問注銷功能,‌這在某些情況下可能是一個安全隱患。‌因此,‌這個配置通常用于開發(fā)環(huán)境或測試環(huán)境,‌以確保用戶可以輕松地測試注銷功能,‌而在生產(chǎn)環(huán)境中,‌出于安全考慮,‌通常會更加限制對注銷頁面的訪問權(quán)限。‌
  • http.csrf():配置是否開啟 CSRF 保護(hù),還可以在開啟之后指定忽略的接口。
  • and():會返回 HttpSecurityBuilder 對象的一個子類(實(shí)際上就是 HttpSecurity),所以 and() 方法相當(dāng)于又回到 HttpSecurity 實(shí)例,重新開啟新一輪的配置。在 Spring Security 的配置中,‌.and() 方法用于將多個安全配置連接起來,‌形成一個連續(xù)的配置鏈。‌這種方法允許開發(fā)者逐步添加和配置安全策略,‌確保每個配置步驟都是基于前一個步驟的結(jié)果進(jìn)行的。‌通過使用 .and() 方法,‌可以構(gòu)建復(fù)雜的安全配置,‌包括身份驗(yàn)證、‌授權(quán)、‌安全防護(hù)等。‌例如,‌在配置 Spring Security 時,‌可能會先設(shè)置用戶認(rèn)證方式,‌然后使用 .and() 方法連接到授權(quán)配置,‌接著可能再次使用 .and() 方法連接到 CSRF 保護(hù)等高級配置。‌這種鏈?zhǔn)脚渲梅绞绞沟么a更加清晰和易于管理。‌
http
    .someConfigurer
        .<some feature of configurer>()
        .<some feature of configurer>()
        .and()
    .someOtherConfigurer
        .<some feature of someOtherConfigurer>()
        ...
        .and()
     ...

如果開啟了 CSRF,則一定在驗(yàn)證頁面加入以下代碼以傳遞 token 值:

<head>
  <meta name="_csrf" th:content="${_csrf.token}"/>
  <!-- default header name is X-CSRF-TOKEN -->
  <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>

如果要提交表單,則需要在表單中添加以下代碼以提交 token 值:

<input type="hidden" th:name="${_csrf.parameterName)" th:value="${_csrf.token)">
  • http.rememberMe():“記住我” 功能,可以指定參數(shù)。
<input class="i-checks" type="checkbox" name="rememberme"/>  記住我

3.配置加密方式

默認(rèn)的加密方式是 BCrypt。只要在安全配置類配置即可使用,見以下代碼:

@Bean
public PasswordEncoder passwordEncoder() {
	// 使用 BCrypt 加密
  return new BCryptPasswordEncoder();
}

在業(yè)務(wù)代碼中,可以用以下方式對密碼迸行加密:

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodePassword = encoder.encode(password);

3.1 BCrypt 加密

BCrypt 是一種基于哈希函數(shù)的加密算法,它使用一個 密碼 和一個 鹽值 作為輸入,生成一個固定長度的 密碼哈希值。這個哈希值在每次密碼輸入時都會重新生成,而且會隨著鹽值的改變而改變。BCrypt 的鹽值是一個隨機(jī)生成的字符串,與密碼一起用于哈希函數(shù)中,使得相同的密碼在每次加密時都會生成不同的哈希值。

在這里插入圖片描述

BCrypt 的另一個重要特點(diǎn)是它使用了一個加密算法來混淆密碼哈希值。這個加密算法使用一個密鑰和一個初始化向量(IV)來加密密碼和鹽值。加密后的數(shù)據(jù)被存儲在數(shù)據(jù)庫中,用于后續(xù)的密碼驗(yàn)證。

BCrypt 的加密過程可以分為以下幾個步驟:

  • 生成鹽值:BCrypt 使用一個隨機(jī)數(shù)生成器生成一個隨機(jī)的 鹽值。這個鹽值是一個隨機(jī)的字符串,用于與密碼一起生成哈希值。
  • 混合鹽值和密碼:將 密碼 和 鹽值 混合在一起,然后使用一個 哈希函數(shù) 生成一個固定長度的 哈希值
  • 加密哈希值:使用一個 加密算法 將哈希值混淆,生成一個 加密的哈希值。這個加密的哈希值被存儲在數(shù)據(jù)庫中。
  • 驗(yàn)證密碼:在驗(yàn)證密碼時,用戶輸入 密碼,系統(tǒng)使用相同的 鹽值、哈希函數(shù) 和 加密算法 生成一個 新的哈希值。然后,將新的哈希值與數(shù)據(jù)庫中的加密哈希值進(jìn)行比較,如果它們匹配,則密碼驗(yàn)證成功。

在這里插入圖片描述

?? BCrypt 加密/匹配工具 - 在線密碼哈希生成與匹配

在這里插入圖片描述

4.自定義加密規(guī)則

除默認(rèn)的加密規(guī)則,還可以自定義加密規(guī)則。具體見以下代碼:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception ( 
	auth.userDetailsService(UserService()).passwordEncoder(new PasswordEncoder() { 
		@Override
		public String encode(CharSequence charSequence) {
			return MD5Util.encode((String) charSequence);
		}
		@Override
		public boolean matches(CharSequence charSequence, String s) {
			return s.equals(MD5Util.encode((String) charSequence));
		}
  });
}

5.配置多用戶系統(tǒng)

一個完整的系統(tǒng)一般包含多種用戶系統(tǒng),比如 “后臺管理系統(tǒng) + 前端用戶系統(tǒng)"。Spring Security 默認(rèn)只提供一個用戶系統(tǒng),所以,需要通過配置以實(shí)現(xiàn)多用戶系統(tǒng)。

比如,如果要構(gòu)建一個前臺會員系統(tǒng),則可以通過以下步驟來實(shí)現(xiàn)。

5.1 構(gòu)建 UserDetailsService 用戶信息服務(wù)接口

構(gòu)建前端用戶 UserSecurityService 類,并繼承 UserDetailsService。具體見以下代碼:

public class UserSecurityService implements UserDetailsService {
	@Autowired
	private UserRepository userRepository;
	@Override
	public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
		User user = userRepository.findByName(name);
		if (user == null) {
			User mobileUser = userRepository.findByMobile(name);
			if (mobileUser == null) {
				User emailUser = userRepository .findByEmail(name);
				if (emailUser == null) {
					throw new UsernameNotFoundException("用戶名,郵箱或手機(jī)號不存在!");
				} else {
					user = userRepository.findByEmail(name);
				}
			} else {
				user = userRepository.findByMobile(name);
			}
		} else if ("locked".equals(user.getStatus())) {
			//被鎖定,無法登錄
			throw new LockedException("用戶被鎖定”);
		}
		return user;
	}
}

5.2 進(jìn)行安全配置

在繼承 WebSecurityConfigurerAdapter 的 Spring Security 配置類中,配置 UserSecurityService 類。

@Bean
UserDetailsService UserService() {
	return new UserSecurityService();
}

如果要加入后臺管理系統(tǒng),則只需要重復(fù)上面步驟即可。

6.獲取當(dāng)前登錄用戶信息的幾種方式

獲取當(dāng)前登錄用戶的信息,在權(quán)限開發(fā)過程中經(jīng)常會遇到。而對新人來說,不太了解怎么獲取,經(jīng)常遇到獲取不到或報(bào)錯的問題。

所以,本節(jié)講解如何在常用地方獲取當(dāng)前用戶信息。

6.1 在 Thymeleaf 視圖中獲取

要 Thymeleaf 視圖中獲取用戶信息,可以使用 Spring Security 的標(biāo)簽特性。

在 Thymeleaf 頁面中引入 Thymeleaf 的 Spring Security 依賴,見以下代碼:

<!DOCTYPE html>
<html lang="zh" xmlns:th=”http://www.thymeleaf.org" 
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
	<!-- 省略 -->
	<body>
		<!-- 匿名 -->
		<div sec:authorize="isAnonymous()">
			未登錄,單擊 <a th:href="@{/home/login}" rel="external nofollow" >登錄</a>
		</div>
		<!-- 已登錄 -->
		<div sec:authorize="isAuthenticated()">
			<p>已登錄</p>
			<p>登錄名: <span sec:authentication="name"></span></p>
			<p>角色: <span sec:authentication="principal.authorities"></span></p>
			<p>id: <span sec:authentication="principal.id"></span></p>
			<p>Username: <span sec:authentication="principal.username"></span></p>
		</div>
	</body>
</html>

這里要特別注意版本的對應(yīng)。如果引入了 thymeleaf-extras-springsecurity 依賴依然獲取不到信息,那么可能是 Thymeleaf 版本和 thymeleaf-extras-springsecurity 的版本不對。

請檢查在 pom.xml 文件的兩個依賴,見以下代碼:

<dependency>
  <groupld>org.springframework.boot</groupld> 
  <artifactld>spring-boot-starter-thymeleaf</artifactld>
</dependency>

<dependency>
  <groupld>org.thymeleaf.extras</groupld>
  <artifactld>thymeleaf-extras-springsecurity5</artifactld>
</dependency>

6.2 在 Controller 中獲取

在控制器中獲取用戶信息有 3 種方式,見下面的代碼注釋。

@GetMapping("userinfo")
public String getProduct(Principal principal, Authentication authentication, HttpServletRequest httpServletRequest) {
  /**
   * Description: 1.通過 Principal 參數(shù)獲取
  */
  String username = principal.getName();
  /**
   * Description: 2.通過 Authentication 參數(shù)獲取
   */
  String userName2 = authentication.getName();
  /**
   * Description: 3.通過 HttpServletRequest 獲取
   */
  Principal httpServletRequestUserPrincipal = httpServletRequest.getUserPrincipal();
  String userName3 = httpServletRequestUserPrincipal.getName();
  return username;
}

6.3 在 Bean 中獲取

在 Bean 中,可以通過以下代碼獲?。?/p>

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
if (!(authentication instanceof AnonymousAuthenticationToken)) {
	String username = authentication.getName();
  return username;
}

在其他 Authentication 類也可以這樣獲取。比如在 UsernamePasswordAuthenticationToken 類中。

如果上面代碼獲取不到,并不是代碼錯誤,則可能是因?yàn)橐韵略蛟斐傻模?/p>

  • ? 要使上面的獲取生效,必須在繼承 WebSecurityConfigurerAdapter 的類中的 http.antMatcher("/*") 的鑒權(quán) URI 范圍內(nèi)。
  • ? 沒有添加 Thymeleaf 的 thymeleaf-extras-springsecurity 依賴。
  • ? 添加了 Spring Security 的依賴,但是版本不對,比如 Spring Security 和 Thymeleaf 的版本不對。

到此這篇關(guān)于SpringBoot配置Spring Security的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot配置Spring Security內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • 如何用匿名內(nèi)部類實(shí)現(xiàn) Java 同步回調(diào)

    如何用匿名內(nèi)部類實(shí)現(xiàn) Java 同步回調(diào)

    這篇文章主要介紹了如何用匿名內(nèi)部類實(shí)現(xiàn) Java 同步回調(diào),幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-10-10
  • Java結(jié)構(gòu)型模式之橋接模式詳解

    Java結(jié)構(gòu)型模式之橋接模式詳解

    橋接模式是一種很實(shí)用的結(jié)構(gòu)型模式,如果系統(tǒng)中某個類存在兩個獨(dú)立變化的維度,通過橋接模式將這兩個維度分離出來,使兩者可以獨(dú)立擴(kuò)展
    2023-02-02
  • IDEA編譯時報(bào)常量字符串過長的解決辦法

    IDEA編譯時報(bào)常量字符串過長的解決辦法

    本文主要介紹了IDEA編譯時報(bào)常量字符串過長的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 解決Mybatis一對多/多對多查詢時只查出了一條數(shù)據(jù)問題

    解決Mybatis一對多/多對多查詢時只查出了一條數(shù)據(jù)問題

    在使用MyBatis進(jìn)行一對多查詢時,若兩張表的ID字段名稱相同,則會導(dǎo)致多的一方數(shù)據(jù)只查詢出來一條,解決方法是修改ID字段名稱,保持不一致,此經(jīng)驗(yàn)供參考,希望對大家有所幫助
    2026-05-05
  • Java繼承Thread類創(chuàng)建線程類示例

    Java繼承Thread類創(chuàng)建線程類示例

    這篇文章主要介紹了Java繼承Thread類創(chuàng)建線程類,結(jié)合實(shí)例形式分析了java線程操作相關(guān)使用技巧與注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • MyBatis實(shí)現(xiàn)MySQL批量插入的示例代碼

    MyBatis實(shí)現(xiàn)MySQL批量插入的示例代碼

    本文主要介紹了MyBatis實(shí)現(xiàn)MySQL批量插入的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • SpringBoot結(jié)合Vue實(shí)現(xiàn)Python在線調(diào)試器

    SpringBoot結(jié)合Vue實(shí)現(xiàn)Python在線調(diào)試器

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何結(jié)合Vue實(shí)現(xiàn)Python在線調(diào)試器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-01-01
  • java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性

    java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性

    這篇文章主要介紹了java生成json實(shí)現(xiàn)隱藏掉關(guān)鍵屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA

    關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA

    這篇文章主要介紹了關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA的問題,文中提供了詳細(xì)的圖文講解,需要的朋友可以參考下,如果有錯誤的地方還請指正
    2023-03-03
  • Spring整合Mybatis的全過程

    Spring整合Mybatis的全過程

    這篇文章主要介紹了Spring整合Mybatis的全過程,包括spring配置文件書寫映射器接口的實(shí)例代碼,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-06-06

最新評論

衡南县| 石首市| 凤翔县| 广州市| 岳西县| 万源市| 甘孜| 水城县| 藁城市| 儋州市| 莲花县| 红安县| 通道| 乐都县| 通辽市| 延边| 磐石市| 金湖县| 海城市| 裕民县| 富锦市| 车致| 苗栗市| 保康县| 嘉兴市| 留坝县| 长沙县| 大厂| 龙川县| 山阴县| 万年县| 丰原市| 荆门市| 榆中县| 泌阳县| 常宁市| 盈江县| 海晏县| 汤原县| 西乌珠穆沁旗| 上饶市|