Servlet 是 Java Web 应用的最常见场景,Spring Security 对 Servlet 的权限认定过程实现了规范化和流程化。
本节主要讨论在 Servlet 应用中,如何通过 Spring Security 实现鉴权。
Servlet 鉴权主要围绕着 FilterSecurityInterceptor 类展开,该类作为一个安全过滤器,被放置在 FilterChainProxy 中。

图 1. Servlet 请求鉴权流程
具体流程如下:
FilterSecurityInterceptor 从 SecurityContextHolder 中获取 Authentication 对象;FilterSecurityInterceptor 从 HttpServletRequest、HttpServletREsponse、 FilterChain 中创建 FilterInvocation 对象;FilterInvocation 对象传递给 SecurityMetadataSource 用来获取 ConfigAttribute 对象集合;Authentication、FilterInvocation 和 ConfigAttribute 对象传递给 AccessDecisionManager 实例验证权限:
AccessDeniedException 异常,并由 ExceptionTranslationFilter 接收并处理;FilterSecurityInterceptor 将控制权交还给 FilterChain,使程序继续执行。默认情况下,Spring Security 的权限要求所有的请求都需要首先通过认证。相当于以下配置描述:
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
);
}
如果我们需要配置 Spring Security 对不同请求有不同的处理规则时,可通过以下方式修改配置:
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.authorizeRequests(authorize -> authorize
.mvcMatchers("/resources/**", "/signup", "/about").permitAll()
.mvcMatchers("/admin/**").hasRole("ADMIN")
.mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().denyAll()
);
}
以上这段代码实现了如下功能:
/resources、/signup、/about 允许任何用户访问;/admin/ 开头的地址都要求用户具有管理员权限 ROLE_ADMIN,其中 ROLE_ 前缀是 Spring Security 默认添加的,用户无需做特殊处理;/db/ 为开头的地址需要同时拥有 ROLE_ADMIN 和 ROLE_DBA 角色;本节讨论了如何用 Spring Security 规范化 Servlet 鉴权过程:
FilterSecurityInterceptor 实现;下节我们讨论如何通过「访问控制表达式」实现多样化的鉴权规则。
0/1000



















