1.概述
Spring Security使用強大的Spring Expression Language(SpEL)提供各種各樣的表達式。大多數這些Security表示式是針對上下文物件(當前經過身份驗證的主體)進行工作的.
這些表示式的評估由SecurityExpressionRoot執行 - 它提供了Web安全性和方法級安全性的基礎。
Spring Security 3.0中引入了使用SpEL表示式作為授權機制的能力,並在Spring Security 4.x中繼續使用,有關Spring Security中表示式的完整列表,請檢視本指南。
2.Web授權
Spring Security提供兩種型別的Web授權 - 基於URL保護整頁,並根據安全規則有條件地顯示JSP頁面的各個部分。
2.1.Full Page授權示例
通過為http元素啟用表示式,可以按如下方式保護URL模式:
<http use-expressions = "true">
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
...
</http>
使用Java配置:
@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN");
}
...
}
Spring Security會自動為任何角色新增字首ROLE_。
此處使用hasRole表示式來檢查當前經過身份驗證的主體是否具有指定的許可權。
2.2.在頁面授權示例
第二種Web授權基於對Security表示式的評估有條件地顯示JSP頁面的某些部分。
讓我們在pom.xml中為Spring Security JSP taglib支援新增所需的依賴項:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
必須在頁面上啟用taglib支援才能使用Security名稱空間:
<%@ taglib prefix="security"
uri="http://www.springframework.org/security/tags" %>
現在可以在頁面上使用hasRole表示式,當頁面渲染時,基於經過身份驗證的人顯示/隱藏HTML元素.
<security:authorize access="hasRole('ROLE_USER')">
This text is only visible to a user
<br/>
</security:authorize>
<security:authorize access="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br/>
</security:authorize>
3.方法級別授權示例 - @PreAuthorize
通過使用註釋,Security表示式還可用於在方法級別保護業務功能。
注釋@PreAuthorize和@PostAuthorize(以及@PreFilter和@PostFilter)支援Spring Expression Language(SpEL)並提供基於表示式的訪問控制。
首先,為了使用方法級安全性,我們需要使用@EnableGlobalMethodSecurity在安全性配置中啟用它:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
}
等效的XML配置:
<global-method-security pre-post-annotations="enabled" />
然後,我們可以使用Spring @PreAuthorize註釋來保護方法:
@Service
public class FooService {
@PreAuthorize("hasRole('ROLE_ADMIN')")
public List<Foo> findAll() { ... }
...
}
現在,只有具有ADMIN角色的使用者才能成功呼叫findAll方法。
請注意,Pre和Post註釋是通過代理進行評估和強制執行的 - 如果使用CGLIB代理,則不能將類和公共方法宣告為final。
4.程式設計檢查角色
如果請求物件可用,還可以在原始Java程式碼中以程式設計方式檢查使用者許可權:
@RequestMapping
public void someControllerMethod(HttpServletRequest request) {
request.isUserInRole("someAuthority");
}
當然,不訪問請求,也可以簡單的手動校驗有特殊許可權的已認證通過的使用者。可以通過各種方式從Spring Security上下文中獲取用戶。
5.總結
本教程簡要介紹了一般使用Spring Security Expressions,特別是hasRole表示式 - 快速介紹如何保護應用程式的各個部分。
有關Web授權示例,請檢視此Github簡單教程。方法級安全性示例也在GitHub上。