9.3.1 使用 Spring 表达式进行安全保护
表 9.4 中的大多数方法都是一维的,也就是说我们可以使用 hasRole() 限制某个特定的角色,但是我们不能在相同的路径上同时通过 hasIpAddress() 限制特定的 IP 地址。
另外,除了表 9.4 定义的方法以外,我们没有办法使用其他的条件。如果我们希望限制某个角色只能在星期二进行访问的话,该怎么办呢?
在第 3 章中,我们看到了如何使用 Spring 表达式语言(Spring Expression Language,SpEL),将其作为装配 bean 属性的高级技术。借助 access() 方法,我们也可以将 SpEL 作为声明访问限制的一种方式。例如,如下就是使用 SpEL 表达式来声明具有 ROLE_SPITTER
角色才能访问 /spitter/me
URL:
这个对 /spitter/me
的安全限制与开始时的效果是等价的,只不过这里使用了 SpEL 来描述安全规则。如果当前用户被授予了给定角色的话,那 hasRole() 表达式的计算结果就为 true。
让 SpEL 更强大的原因在于,hasRole() 仅是 Spring 支持的安全相关表达式中的一种,表 9.5 列出了 Spring Security 支持的所有 SpEL 表达式。
安全表达式 | 计算结果 |
authentication | 用户的认证对象 |
denyAll | 结果始终为 false |
hasAnyRole(list of roles) | 如果用户被授予了列表中任意的指定角色,结果为 true |
hasRole(role) | 如果用户被授予了指定的角色,结果为 true |
hasIpAddress(IP Address) | 如果请求来自指定 IP 的话,结果为 true |
isAnonymous() | 如果当前用户为匿名用户,结果为 true |
isAuthenticated() | 如果当前用户进行了认证的话,结果为 true |
isFullyAuthenticated() | 如果当前用户进行了完整认证的话(不是通过 Remember-me 功能进行的认证),结果为 true |
isRememberMe() | 如果当前用户是通过 Remember-me 自动认证的,结果为 true |
permitAll | 结果始终为true |
principal | 用户的principal对象 |
在掌握了 Spring Security 的 SpEL 表达式后,我们就能够不再局限于基于用户的权限进行访问限制了。例如,如果你想限制 /spitter/me
URL 的访问,不仅需要 ROLE_SPITTER,还需要来自指定的 IP 地址,那么我们可以按照如下的方式调用 access() 方法:
我们可以使用 SpEL 实现各种各样的安全性限制。我敢打赌,你已经在想象基于 SpEL 所能实现的那些有趣的安全性限制了。
但现在,让我们看一下 Spring Security 拦截请求的另外一种方式:强制通道的安全性。
Last updated