1. 概述
Spring Security 提供良好的支持,可以與 Spring Data 集成。前者負責應用程序的安全方面,而後者則提供方便的數據庫訪問,用於訪問應用程序的數據。
在本文中,我們將討論如何將 Spring Security 與 Spring Data 集成,以啓用更具用户特定性的查詢。
2. Spring Security + Spring Data Configuration
在對 Spring Data JPA 的介紹中,我們看到了如何在 Spring 項目中設置 Spring Data。為了啓用 Spring Security 和 Spring Data,通常可以採用基於 Java 或 XML 的配置。
2.1. Java 配置
請記住,在《Spring Security 登錄表單》(第 4 & 5 部分)中,我們可以使用基於註解的配置將 Spring Security 添加到我們的項目中:
@EnableWebSecurity
public class WebSecurityConfig {
// Bean definitions
}為了啓用 Spring Data 在 Spring Security 中的使用,我們只需將此 Bean 添加到 WebSecurityConfig 中:
為了啓用 Spring Data 在 Spring Security 中的使用,我們只需將此 Bean 添加到 WebSecurityConfig 中:
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}上述定義允許激活對 spring-data 上的類上定義的特定表達式進行的自動解析。
2.2. XML 配置
XML 形式的配置首先包含 Spring Security 命名空間:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
...
</beans:beans>類似於基於 Java 的配置,對於基於 XML 或命名空間進行的配置,我們會在 XML 配置文件中添加 SecurityEvaluationContextExtension Bean:
<bean class="org.springframework.security.data.repository
.query.SecurityEvaluationContextExtension"/>定義 SecurityEvaluationContextExtension 使 Spring Security 中的所有常用表達式均可在 Spring Data 查詢中訪問。
這些常用表達式包括 principal、authentication、isAnonymous()、hasRole([role])、isAuthenticated、等。
3. 示例用法
讓我們考慮一下 Spring Data 和 Spring Security 的一些用例。
3.1. 限制 AppUser 字段更新
在本文檔中,我們將探討如何限制 AppUser 的 lastLogin 字段更新,僅允許當前已認證的用户進行更新。
這意味着,每當 updateLastLogin 方法被觸發時,它只會更新當前已認證用户的 lastLogin 字段。
為了實現這一點,我們在 UserRepository 接口中添加了以下查詢:
@Query("UPDATE AppUser u SET u.lastLogin=:lastLogin WHERE"
+" u.username = ?#{ principal?.username }")
@Modifying
@Transactional
void updateLastLogin (@Param("lastLogin") Date lastLogin);<p>在沒有 Spring Data 和 Spring Security 集成的情況下,我們通常需要將用户名作為參數傳遞給 <em >updateLastLogin</em>。</p>
<p>如果提供錯誤的用户名憑據,登錄過程將會失敗,因此無需擔心訪問權限驗證。</p>
3.2. 使用分頁檢索特定AppUser內容
另一個 Spring Data 和 Spring Security 完美協作的場景是,我們需要從數據庫中檢索屬於當前認證用户的內容。
例如,如果有一個推特應用程序,我們可能希望在用户個性化時間線頁面上顯示當前用户創建或點讚的推文。
當然,這可能涉及編寫查詢來與數據庫中的一個或多個表進行交互。藉助 Spring Data 和 Spring Security,這就像編寫:
public interface TweetRepository extends PagingAndSortingRepository<Tweet, Long>, CrudRepository<Tweet, Long> {
@Query("SELECT twt FROM Tweet twt JOIN twt.likes AS lk WHERE lk = ?#{ principal?.username }" +
" OR twt.owner = ?#{ principal?.username }")
Page<Tweet> getMyTweetsAndTheOnesILiked(Pageable pageable);
}為了使我們的結果分頁顯示,我們的 TweetRepository 擴展了上述接口定義中的 PagingAndSortingRepository。
從 Spring Data Commons 3.0 開始,為了進行一些重構,將接口進行解耦:CrudRepository, ListCrudRepository, PagingAndSortingRepository 和 ListPagingAndSortingRepository 擁有中心接口 Repository。 這種做法的一個缺點是,如果需要進行 CRUD 操作,則必須擴展特定於 CRUD 的接口。
4. 結論
Spring Data 和 Spring Security 集成為在 Spring 應用程序中管理身份驗證狀態提供了很大的靈活性。
在本課程中,我們探討了如何將 Spring Security 添加到 Spring Data 中。有關 Spring Data 或 Spring Security 的其他強大功能,請參閲我們的 Spring Data 和 Spring Security 文章集合。