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上。