本文来说下security安全表达式
文章目录
概述
让我们开始看安全表达式
- 有角色,有任何角色
- hasAuthority , hasAnyAuthority
- 全部允许,全部拒绝
- isAnonymous , isRememberMe , isAuthenticated , isFullyAuthenticated
- 主体,认证
- 拥有权限
现在让我们详细介绍其中的每一个。
hasRole, hasAnyRole
让我们看一下这个例子:
@Override
protected void configure(final HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/*").hasRole("ADMIN")
.antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
...
}
在此示例中,我们指定对以/auth/开头的所有链接的访问权限仅限于以角色USER或角色ADMIN登录的用户。此外,要访问以/auth/admin/开头的链接,我们需要在系统中具有ADMIN角色。
hasAuthority, hasAnyAuthority
Spring 中的角色和权限是相似的。
主要区别在于,角色具有特殊的语义——从 Spring Security 4 开始,任何与角色相关的方法都会自动添加“ ROLE_ ”前缀(如果它还没有)。
所以hasAuthority(‘ROLE_ADMIN’)类似于hasRole(‘ADMIN’)因为’ ROLE_ '前缀是自动添加的。
但是使用权限的好处是我们根本不必使用ROLE_前缀。
这是我们定义具有特定权限的用户的快速示例:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(encoder().encode("user1Pass"))
.authorities("USER")
.and().withUser("admin").password(encoder().encode("adminPass"))
.authorities("ADMIN");
}
然后我们当然可以使用这些权限表达式:
@Override
protected void configure(final HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/*").hasAuthority("ADMIN")
.antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
...
}
正如我们所看到的 - 我们在这里根本没有提到角色。此外,从 Spring 5 开始,我们需要一个 PasswordEncoder bean:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
全部允许,全部拒绝
这两个注释也很简单。我们可能会允许访问我们服务中的某些 URL,或者我们可能会拒绝访问。
让我们看一下这个例子:
...
.antMatchers("/*").permitAll()
...
使用此配置,我们将授权所有用户(匿名和登录)访问以“/”开头的页面(例如,我们的主页)。
我们还可以拒绝访问我们的整个 URL 空间:
...
.antMatchers("/*").denyAll()
...
isAnonymous, isRememberMe, isAuthenticated, isFullyAuthenticated
在本小节中,我们关注与用户登录状态相关的表达式。让我们从没有登录我们页面的用户开始。通过在 Java 配置中指定以下内容,我们允许所有未经授权的用户访问我们的主页:
...
.antMatchers("/*").anonymous()
...
如果我们想保护每个使用它的人都需要登录的网站,我们需要使用isAuthenticated()方法:
...
.antMatchers("/*").authenticated()
...
此外,我们还有两个额外的表达式,isRememberMe()和isFullyAuthenticated()。通过使用 cookie,Spring 启用了记住我的功能,因此无需每次都登录系统。您可以在此处阅读有关“记住我”的更多信息。
为了向仅通过记住我功能登录的用户提供访问权限,我们可以使用:
...
.antMatchers("/*").rememberMe()
...
最后,即使用户已经登录,我们服务的某些部分也要求用户再次进行身份验证。例如,用户想要更改设置或付款信息;在系统的更敏感区域要求手动身份验证当然是一种很好的做法。
为此,我们可以指定isFullyAuthenticated(),如果用户不是匿名用户或记住我的用户,则返回true:
...
.antMatchers("/*").fullyAuthenticated()
...
主体,身份验证
这些表达式允许分别从SecurityContext访问代表当前授权(或匿名)用户的主体对象和当前Authentication对象。
例如,我们可以使用principal加载用户的电子邮件、头像或登录用户可访问的任何其他数据。
和认证提供了有关的全部信息验证对象,其授予的权限一起。
hasPermission API
此表达式已记录并旨在在表达式系统和 Spring Security 的 ACL 系统之间架起桥梁,允许我们根据抽象权限指定对单个域对象的授权约束。
让我们看一个例子。我们有一项服务,允许与主编合作撰写文章,决定应该发表其他作者提出的哪篇文章。
为了允许使用此类服务,我们可能会创建以下具有访问控制方法的方法:
@PreAuthorize("hasPermission(#articleId, 'isEditor')")
public void acceptArticle(Article article) {
…
}
只有经过授权的用户才能调用此方法,并且用户需要在服务中拥有isEditor权限。