如何使用 Spring Security 保護您的 Spring 應用程序
Spring Security 是通過身份驗證和授權過程保護應用程序的有效手段。默認情況下,該框架要求應用程序中的每個單獨的 URL 或網頁都必須使用全球認可的唯一最終用戶的憑據進行訪問。
所提出的方法表現出非凡的適應性。它可以為程序中的每個單獨的 HTTP 請求路由以及不同的最終用戶制定定制的安全法規。因此,消除對不需要用戶認證的網頁(例如主頁)施加的安全限制變得可行。此外,該方法允許指定特定類別用戶的角色分配和權限級別。
將 Spring Security 添加到您的應用程序中
將 Spring Security 合併到現有或新創建的 Spring Boot 應用程序中時,存在兩種主要的實現方法。第一個涉及在利用 Spring Initializr 平台生成新 Spring Boot 項目的過程中選擇集成。或者,人們可以選擇將其包含在項目的構建規範中,方法是在創建項目後將其添加到所述文檔中的依賴項列表中。
當通過第一個選項選擇時,Gradle 項目的配置文件被標識為 build.gradle,而 Maven 項目中的配置文件被標識為 aspom.xml。
您的 build.gradle 文件應包含特定的依賴項,如下所述:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
上述投資組合 XML 文件預計將包含特定的依賴項,概述如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
所提供的示例應用程序可以通過 GitHub 存儲庫訪問,該存儲庫根據 MIT 許可證條款免費提供它,允許用戶根據其指定的條件使用它。
使用 Spring Security
將 Spring Security 模塊合併到您的項目中後,您現在就可以立即部署其功能。為了演示這一點,只需啟動您的程序並將瀏覽器定向到 Spring Boot 的官方網站或您自己的應用程序中的任何指定頁面。提供的示例採用主控制器來管理針對預配置 URL http://localhost:8080 的傳入請求的標準處理。
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@GetMapping("/")
public String home() {
return "Welcome!";
}
}
上述應用程序在合併上述單獨控制器類後,產生如下初步觀點:
第一次訪問該應用程序時,將被定向到 localhost:8080/login 頁面。在訪問程序的任何其他部分之前,用戶必須輸入預定義的用戶名(即“user”)以及隨機創建的密碼(可以在命令提示符中找到)。命令提示符會生成類似於以下示例的消息:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
隨後重新啟動應用程序後,自動生成的密碼將發生更改;但是,用戶名應保持不變。通過輸入預定義的用戶名和密碼,用戶將被重定向到應用程序內的相關界面。
自定義 Spring Security
為了根據您的具體要求定制應用程序的安全性,有必要修改Spring Security提供的默認配置。然而,在這樣做之前,假設您已經使用 Spring 設置了一個基本的 Web 應用程序,為了使用這個特定的示例,必須滿足幾個額外的先決條件:
⭐Spring Data JPA
⭐MySQL JDBC 驅動程序
⭐百里香葉
⭐龍目島
Thymeleaf 框架的利用可以生成多個視角,而 Lombok 則簡化了基於對象的類結構內的編碼過程。此外,與 JPA 庫和 MySQL 驅動程序的集成有助於與 MySQL 數據庫的交互,儘管用戶也可以自行決定使用替代數據庫。要配置此類交互,需要調整位於資源目錄中的 applications.properties 文件中的配置設置。
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
為了使用用戶名“root”和密碼“(1234)”建立與 MySQL 本地實例(表示為“spring\_security”)的連接,必須通過更新來正確配置所提供的配置代碼相應的相關信息以確保與特定數據庫配置的兼容性。
添加任何必要的依賴項並建立數據庫後,您可以開始確定應用程序將包含的視角數量。此外,考慮每個觀點的安全措施也很重要。在我們的說明性示例中,應用程序中包含六個不同的有利點。
⭐首頁
⭐註冊頁面
⭐登錄頁面
⭐退出頁面
⭐用戶頁面
⭐錯誤頁面
為了讓用戶在“用戶頁面”上訪問他們的個人信息,他們必須首先註冊並登錄應用程序。只有那些已經註冊的人才被授予查看此頁面的權限。此外,除了 Spring Boot 標準產品提供的包之外,還需要在應用程序中額外建立四個包。
註冊控制器類
Controller 包包含負責處理 HTTP 請求的類。通常,單個控制器類處理與特定網頁功能相對應的請求,例如在 WebController 類的實例中。另一方面,RegistrationView 需要管理不同的功能,因此需要一個專用的私有控制器類。
@Controller
@RequestMapping("/register")
public class RegistrationController {
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
public RegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder) {
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm() {
return "registration";
}
@PostMapping
public String processRegistration(RegistrationForm form) {
userRepo.save(form.toUser(passwordEncoder));
return "redirect:/login";
}
}
RegistrationController
充當我們應用程序中安全功能的入口點,它處理針對 localhost:8080/register
的請求。這由“@RequestMapping”註釋指示,該註釋指定該控制器旨在處理的特定請求類型。
@GetMapping
註解表示當應用程序遇到/register
的請求時,registrationForm()
方法負責處理這個請求並渲染相應的註冊視圖。
訪問者單擊註冊按鈕後,@PostMapping 註釋就會發揮作用。 processRegistration() 方法允許您使用 UserRepository 類將從 RegistrationForm 類獲取的用戶數據發佈到數據庫。但在存儲這些數據之前, processRegistration() 方法使用 [ Spring ](https://docs.spring.io/spring-security/site/docs/4.2.4.RELEASE/apidocs/org/springframework 加密用戶的密碼/security/crypto/password/PasswordEncoder.html)PasswordEncoder 接口。
創建新的安全配置
利用 Spring 3.1 的引入,開發人員現在能夠通過使用類而不是依賴基於 XML 的配置,採用基於 Java 的方法來配置 Spring Security。這個過程的關鍵是包括
@Configuration
public class SecurityConfiguration {
}
@Configuration 註解表示後續類構成一個配置類,它有助於為 Spring 應用程序上下文提供組件。該容器充當 Spring 構建和管理應用程序的各種元素(或組成部分)的一種手段。在“SecurityConfiguration”類中,提供的初始成分由“passwordEncoder”名稱表示。
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
RegistrationController
依賴於 passwordEncoder
bean 在將新生成的密碼存儲到數據庫之前對其進行編碼。此外,“SecurityConfiguration”需要合併“userDetailsService”bean 才能正常運行。
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo) {
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
throw new UsernameNotFoundException("Customer '" \+ username \+ "' not found");
};
}
userDetailsService bean 使用 Spring Security 的 UserDetailsService 接口來檢索用戶的用戶名和密碼以進行身份驗證,在客戶登錄會話期間。因此,一旦客戶單擊登錄視圖中的登錄按鈕,userDetailsService bean 就會立即啟動。
通過使用 UserRepository 接口,userDetailsService bean 被授予對數據庫中存儲的用戶綜合集合的訪問權限。該接口隨後使用 UserRepository 來識別其憑據與所提供的用戶名和密碼相對應的用戶,之後它檢索並返回與該特定客戶相關的所有相關信息作為聚合實體。
成功驗證所提供的憑據後,如果檢索到的實體對應於註冊客戶端,則他們將被授予使用平台功能的權限。如果驗證失敗並且輸入了無效的用戶名或密碼組合,界面將進行無縫重新加載,邀請最終用戶輸入合法的登錄信息進行另一次嘗試。
過濾器鏈
Spring Security 的 SecurityFilterChain 接口是一個有用的應用程序編程接口(API)這在 Spring Security 配置中起著至關重要的作用。該接口與Spring Security 的 HttpSecurity一起使用類來為特定的 HTTP 請求創建過濾器鏈。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin-> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout-> logout.logoutSuccessUrl("/logout"));
return http.build();
}
提供的代碼利用“filterChain”bean 中的“HttpSecurity”類,通過根據用戶角色限制對特定端點的訪問來實施安全措施。具體來說,“HttpSecurity”配置僅向擁有“USER”角色的用戶授予對“/user”端點的訪問權限,該角色是通過實現每個新創建的客戶對像中的“getAuthorities()”方法來確定的。
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
過濾器鏈允許未經身份驗證的用戶不受限制地訪問應用程序中的每個 URL,因為它利用 HttpSecurity 類提供的表單登錄和註銷過程。
這些技術的實施可以為已成功完成操作的用戶提供無縫導航。例如,輸入有效憑據並單擊“/login”頁面上的“登錄”按鈕後,用戶會毫不費力地重定向到“/user”頁面,而無需用戶進行任何進一步的干預。
總之,filterChain bean 構建並生成一個過濾器鏈,使經過身份驗證的最終用戶能夠訪問軟件平台。 SecurityConfiguration 配置類中所有三個組件的集體功能是保護您的應用程序免受未經授權的訪問。
filterChain bean 在確定每個傳入 HTTP 請求的授權層方面起著關鍵作用。隨著附加網頁添加到應用程序中,它的影響力會增加,從而允許 filterChain bean 建立其安全級別。
Spring Security 的主要好處
Spring Security 提供了一系列廣泛的功能,用於管理應用程序域內授予訪問權限的個人以及授予這些人員的權限範圍(利用其強大的用戶角色名冊)。開發軟件解決方案時,實施高效的訪問控制機制是最重要的考慮因素之一。由於訪問限制措施不足,為廣泛的用戶提供不受限制的訪問可能會無意中導致大量費用和潛在的安全漏洞。