4.3.1 保护请求
需要确保 /design 和 /orders 的请求仅对经过身份验证的用户可用;应该允许所有用户发出所有其他请求。下面的 configure() 实现就是这样做的:
对 authorizeRequests() 的调用返回一个对象(ExpressionInterceptUrlRegistry),可以在该对象上指定 URL 路径和模式以及这些路径的安全需求。在这种情况下,指定两个安全规则:
对于 /design 和 /orders 的请求应该是授予 ROLE_USER 权限的用户的请求。
所有的请求都应该被允许给所有的用户。
这些规则的顺序很重要。首先声明的安全规则优先于较低级别声明的安全规则。如果交换这两个安全规则的顺序,所有请求都将应用 permitAll(),那么关于 /design 和 /orders 请求的规则将不起作用。
hasRole() 和 permitAll() 方法只是声明请求路径安全需求的两个方法。表 4.1 描述了所有可用的方法。
表 4.1 定义被保护路径的配置方法
方法 | 做了什么 |
access(String) | 如果 SpEL 表达式的值为 true,则允许访问 |
anonymous() | 默认用户允许访问 |
authenticated() | 认证用户允许访问 |
denyAll() | 无条件拒绝所有访问 |
fullyAuthenticated() | 如果用户是完全授权的(不是记住用户),则允许访问 |
hasAnyAuthority(String...) | 如果用户有任意给定的权限,则允许访问 |
hasAnyRole(String...) | 如果用户有任意给定的角色,则允许访问 |
hasAuthority(String) | 如果用户有给定的权限,则允许访问 |
hasIpAddress(String) | 来自给定 IP 地址的请求允许访问 |
hasRole(String) | 如果用户有给定的角色,则允许访问 |
not() | 拒绝任何其他访问方法 |
permitAll() | 无条件允许访问 |
rememberMe() | 允许认证了的同时标记了记住我的用户访问 |
表 4.1 中的大多数方法为请求处理提供了基本的安全规则,但是它们是自我限制的,只支持那些方法定义的安全规则。或者,可以使用 access() 方法提供 SpEL 表达式来声明更丰富的安全规则。Spring Security 扩展了 SpEL,包括几个特定于安全性的值和函数,如表 4.2 所示。
表 4.2 Spring Security 对 SpEL 的扩展
Security 表达式 | 意指什么 |
authentication | 用户认证对象 |
denyAll | 通常值为 false |
hasAnyRole(list of roles) | 如果用户有任何给定的角色,则为 true |
hasRole(role) | 如果用户有给定的角色,则为 true |
hasIpAddress(IP Address) | 如果请求来自给定 IP 地址,则为 true |
isAnonymous() | 如果用户是默认用户,则为 true |
isAuthenticated() | 如果用户是认证了的,则为 true |
isFullyAuthenticated() | 如果用户被完全认证了的(不是使用记住我进行认证),则为 true |
isRememberMe() | 如果用户被标记为记住我后认证了,则为 true |
permitAll() | 通常值为 true |
principal | 用户 pricipal 对象 |
表 4.2 中的大多数安全表达式扩展对应于表 4.1 中的类似方法。实际上,使用 access() 方法以及 hasRole() 和 permitAll 表达式,可以按如下方式重写 configure()。
乍一看,这似乎没什么大不了的。毕竟,这些表达式只反映了已经对方法调用所做的工作。但是表达式可以灵活得多。例如,假设(出于某种疯狂的原因)只想允许具有 ROLE_USER 权限的用户在周二(例如,在周二)创建新的 Taco;你可以重写表达式如下:
使用基于 SpEL 的安全约束,这种可能性实际上是无限的。我敢打赌,你已经在构思基于 SpEL 的有趣的安全约束了。
只需使用 access() 和程序清单 4.9 中的 SpEL 表达式,就可以满足 Taco Cloud 应用程序的授权需求。现在,让我们来看看如何定制登录页面来适应 Taco Cloud 应用程序的外观。
最后更新于