Spring 实战(第四版)
Search…
Spring 实战(第四版)
Spring 实战(第 4 版)
第一部分 Spring 的核心
第 1 章 Spring 之旅
第 2 章 装配 Bean
第 3 章 高级装配
第 4 章 面向切面的 Spring
第二部分 Web 中的 Spring
第 5 章 构建 Spring Web 应用程序
第 6 章 渲染 Web 视图
第 7 章 Spring MVC 的高级技术
第 8 章 使用 Spring Web Flow
第 9 章 保护 Web 应用
9.1 Spring Security 简介
9.2 选择查询用户详细信息的服务
9.3 拦截请求
9.3.1 使用 Spring 表达式进行安全保护
9.3.2 强制通道的安全性
9.3.3 防止跨站请求伪造
9.4 认证用户
9.5 保护视图
9.6 小结
第三部分 后端中的 Spring
第 10 章 通过 Spring 和 JDBC 征服数据库
第 11 章 使用对象-关系映射持久化数据
第 12 章 使用 NoSQL 数据库
第 13 章 缓存数据
第 14 章 保护方法应用
第四部分 Spring 集成
第 15 章 使用远程服务
第 16 章 使用 Spring MVC 创建 REST API
第 17 章 Spring 消息
第 18 章 使用 WebSocket 和 STOMP 实现消息功能
第 19 章 使用 Spring 发送 Email
第 20 章 使用 JMX 管理 SpringBean
第 21 章 借助 Spring Boot 简化 Spring 开发
Powered By
GitBook
9.3 拦截请求
在前面的 9.1.3 小节中,我们看到一个特别简单的 Spring Security 配置,在这个默认的配置中,会要求所有请求都要经过认证。有些人可能会说,过多的安全性总比安全性太少要好。但也有一种说法就是要适量地应用安全性。
在任何应用中,并不是所有的请求都需要同等程度地保护。有些请求需要认证,而另一些可能并不需要。有些请求可能只有具备特定权限的用户才能访问,没有这些权限的用户会无法访问。
例如,考虑 Spittr 应用的请求。首页当然是公开的,不需要进行保护。类似地,因为所有的 Spittle 都是公开的,所以展现 Spittle 的页面不需要安全性。但是,创建 Spittle 的请求只有认证用户才能执行。同样,尽管用户基本信息页面是公开的,不需要认证,但是,如果要处理
/spitters/me
请求,并展现当前用户的基本信息时,那么就需要进行认证,从而确定要展现谁的信息。
对每个请求进行细粒度安全性控制的关键在于重载 configure(HttpSecurity) 方法。如下的代码片段展现了重载的 configure(HttpSecurity) 方法,它为不同的 URL 路径有选择地应用安全性:
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
authorizeRequests
()
.
antMatchers
(
"/spitters/me"
).
authenticated
()
.
antMatchers
(
HttpMethod
.
POST
,
"/spittles"
).
authenticated
()
.
anyRequest
().
permitAll
();
}
configure() 方法中得到的 HttpSecurity 对象可以在多个方面配置 HTTP 的安全性。在这里,我们首先调用 authorizeRequests(),然后调用该方法所返回的对象的方法来配置请求级别的安全性细节。其中,第一次调用 antMatchers() 指定了对
/spitters/me
路径的请求需要进行认证。第二次调用 antMatchers() 更为具体,说明对
/spittles
路径的 HTTP POST 请求必须要经过认证。最后对 anyRequests() 的调用中,说明其他所有的请求都是允许的,不需要认证和任何的权限。
antMatchers() 方法中设定的路径支持 Ant 风格的通配符。在这里我们并没有这样使用,但是也可以使用通配符来指定路径,如下所示:
.
antMatchers
(
"/spitter/**"
).
authenticated
();
我们也可以在一个对 antMatchers() 方法的调用中指定多个路径:
.
antMatchers
(
"/spitter/**"
,
"/spittles/mine"
).
authenticated
();
antMatchers() 方法所使用的路径可能会包括 Ant 风格的通配符,而 regexMatchers() 方法则能够接受正则表达式来定义请求路径。例如,如下代码片段所使用的正则表达式与
/spitters/**
(Ant风格)功能是相同的:
.
regexMatchers
(
"/spitter/.*"
).
authenticated
();
除了路径选择,我们还通过 authenticated() 和 permitAll() 来定义该如何保护路径。authenticated() 要求在执行该请求时,必须已经登录了应用。如果用户没有认证的话,Spring Security 的 Filter 将会捕获该请求,并将用户重定向到应用的登录页面。同时,permitAll() 方法允许请求没有任何的安全限制。 除了 authenticated() 和 permitAll() 以外,还有其他的一些方法能够用来定义该如何保护请求。表 9.4 描述了所有可用的方案。
方法
能够做什么
access(String)
如果给定的 SpEL 表达式计算结果为 true,就允许访问
anonymous()
允许匿名用户访问 authenticated() 允许认证过的用户访问
denyAll()
无条件拒绝所有访问
fullyAuthenticated()
如果用户是完整认证的话(不是通过Remember-me 功能认证的),就允许访问
hasAnyAuthority(String...)
如果用户具备给定权限中的某一个的话,就允许访问
hasAnyRole(String...)
如果用户具备给定角色中的某一个的话,就允许访问
hasAuthority(String)
如果用户具备给定权限的话,就允许访问
hasIpAddress(String)
如果请求来自给定 IP 地址的话,就允许访问
hasRole(String)
如果用户具备给定角色的话,就允许访问
not()
对其他访问方法的结果求反
permitAll()
无条件允许访问
rememberMe()
如果用户是通过 Remember-me 功能认证的,就允许访问
通过使用表 9.4 中的方法,我们所配置的安全性能够不仅仅限于认证用户。例如,我们可以修改之前的 configure() 方法,要求用户不仅需要认证,还要具备 ROLE_SPITTER 权限:
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
authorizeRequests
()
.
antMatchers
(
"/spitters/me"
).
hasAuthority
(
"ROLE_SPITTER"
)
.
antMatchers
(
HttpMethoed
.
POST
,
"/spitters"
).
hasAuthority
(
"ROLE_SPITTER"
)
.
anyRequest
().
permitAll
();
}
作为替代方案,我们还可以使用 hasRole() 方法,它会自动使用
ROLE_
前缀:
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
authorizeRequests
()
.
antMatchers
(
"/spitters/me"
).
hasRole
(
"SPITTER"
)
.
antMatchers
(
HttpMethoed
.
POST
,
"/spitters"
).
hasRole
(
"SPITTER"
)
.
anyRequest
().
permitAll
();
}
我们可以将任意数量的 antMatchers()、regexMatchers() 和 anyRequest() 连接起来,以满足 Web 应用安全规则的需要。但是,我们需要知道,这些规则会按照给定的顺序发挥作用。所以,很重要的一点就是将最为具体的请求路径放在前面,而最不具体的路径(如 anyRequest())放在最后面。如果不这样做的话,那不具体的路径配置将会覆盖掉更为具体的路径配置。
Previous
9.2.4 配置自定义的用户服务
Next
9.3.1 使用 Spring 表达式进行安全保护
Last modified
2yr ago
Copy link