Chapter 15. 基于表达式的权限控制

Spring Security 3.0介绍了使用Spring EL表达式的能力,作为一种验证机制 添加简单的配置属性的使用和访问决策投票,就像以前一样。 基于表达式的安全控制是建立在相同架构下的,但是允许使用复杂的布尔逻辑 包含在单独的表达式中。

15.1. 概述

Spring Security使用Spring El来支持表达式,你应该看一下如何工作的 如果你对深入了解这个话题感兴趣的话。表达式是执行在一个“根对象” 上的,作为一部分执行上下文。Spring Security使用特定的类对应web和方法安全,作为根对象, 为了提供内建的表达式,访问值,比如当前的认证主体。

15.1.1. 常用内建表达式

表达式根对象的基本类是SecurityExpressionRoot。 这个提供了一些常用的表达式,都可以在web和method权限控制中使用。

Table 15.1. 常用内建表达式

表达式 说明
hasRole([role]) 返回 true 如果当前主体拥有特定角色。
hasAnyRole([role1,role2]) 返回 true 如果当前主体拥有任何一个提供的角色 (使用逗号分隔的字符串队列)
principal 允许直接访问主体对象,表示当前用户
authentication 允许直接访问当前 Authentication对象 从SecurityContext中获得
permitAll 一直返回true
denyAll 一直返回false
isAnonymous() 如果用户是一个匿名登录的用户 就会返回 true
isRememberMe() 如果用户是通过remember-me 登录的用户 就会返回 true
isAuthenticated() 如果用户不是匿名用户就会返回true
isFullyAuthenticated() 如果用户不是通过匿名也不是通过remember-me登录的用户时, 就会返回true

15.2. Web 安全表达式

为了保护单独的URL,你需要首先把<http>的 use-expressions属性设置为true。Spring Security会把 <intercept-url>access当做包含了Spring EL表达式。 表达式应该返回boolean,定义访问是否应该被允许,比如:

  <http use-expressions="true">
<intercept-url pattern="/admin*"
access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
...
</http>

这里我们已经定义了应用的“admin”范围(通过URL模式定义的) 应该只对拥有“admin”权限的用户有效,并且用户要在本地子网的IP地址下。 我们已经看到了内建的hasRole表达式,在上一章节。 表达式hasIpAddress是一个附加的内建表达式,是由web安全提供的。 它是由WebSecurityExpressionRoot定义的,它的实例作为表达式根对象 当执行web权限表达式时。这个对象也直接暴露了HttpServletRequest对象 使用request这个名字,所以你可以直接调用request在一个表达式里。

如果使用了表达式,一个WebExpressionVoter会被添加到 AccessDecisionManager中,这是被命名空间创建的。 所以如果你没有使用命名空间还希望使用表达式,你必须把这些添加到你的配置中。

15.3. 方法安全表达式

方法安全有一点儿复杂,比单独允许和拒绝规则来说。Spring Security 3.0介绍了一些新注解, 为了对复杂的表达式进行支持。

15.3.1. @Pre 和 @Post 注解

这里有四个注解,支持表达式属性允许进行前置和后置调用验证检测,也支持过滤提交的 集合参数或返回值。它们是@PreAuthorize@PreFilter@PostAuthorize 和 @PostFilter。它们可以通过 global-method-security 命名空间元素启用:

<global-method-security pre-post-annotations="enabled"/>

15.3.1.1. 访问控制使用 @PreAuthorize 和 @PostAuthorize

使用最广泛的注解是@PreAuthorize,它可以决定一个方法是否可以被调用。 比如(来自“Contacts”实例应用)

  @PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);

这意味着只允许拥有"ROLE_USER"角色的用户访问。 很明显,相同的事情可以简单实用传统的配置方法,简单的配置属性来要求角色。 但是如果是这样呢:

  @PreAuthorize("hasPermission(#contact, 'admin')")
public void deletePermission(Contact contact, Sid recipient, Permission permission);

这里我们其实使用了方法参数作为表达式的一部分来决定是否当前的用户拥有“admin” 表达式对给定的contract。内建的 hasPermission()表达式链接到 Spring Security ACL模块,通过applicaton context。你可以访问任何方法参数,通过名称 就像表达式的变量,在编译的时候使用debug信息。任何Spring EL功能都可以在表达式里使用, 所以你可以访问参数的属性。比如,如果你希望特定的方法只允许访问一个用户名和contract匹配, 你可以写成

  @PreAuthorize("#contact.name == authentication.name)")
public void doSomething(Contact contact);

这里我们访问了另一个内建的表达式,authentication, 它是保存在安全上下文里的Authentication实例。 你也可以直接访问它的“principal”属性, 使用principal表达式。这个值一般是一个 UserDetails实例,所以你可能使用一个 像是principal.username或是 principal.enabled的表达式。

不太常见的是,你可能希望之星一个访问控制检测,在方法调用之后。这个可以使用 @PostAuthorize 注解。为了访问一个方法的返回值, 使用表达式中的内建名称returnObject

15.3.1.2. 过滤使用 @PreFilter 和 @PostFilter

你可能已经知道了,Spring Security支持对集合和数据的过滤, 现在也可以使用表达式实现了。通常是用在一个方法的返回值中。比如:

  @PreAuthorize("hasRole('ROLE_USER')")
@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, 'admin')")
public List<Contact> getAll();

当使用@PostFilter注解时,Spring Security遍历返回的集合 删除任何表达式返回false的元素。名字filterObject引用 集合中的当前对象。你也可以在方法调用之前进行过滤,使用@PreFilter 虽然很少需要这样做。这个语法是一样的,但是如果这里有更多参数,都是集合类型 然后你必须使用注解的filterTarget属性选择其中一个。

注意过滤显然不是一个让你读取数据查询的解决方法。如果你过滤大型集合,删除很多实体, 然后这就会是非常没有效率的。

spring security注解(1)的更多相关文章

  1. spring security 注解@EnableGlobalMethodSecurity详解

     1.Spring Security默认是禁用注解的,要想开启注解,需要在继承WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解 ...

  2. Spring Security 学习总结

    Spring Security Spring Security是基于Spring提供声明式安全保护的安全性框架.Spring Security提供了完整的安全性解决方案,能够在Web请求级别和方法调用 ...

  3. Spring Boot + Spring Cloud 实现权限管理系统 (Spring Security 版本 )

    技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro 也足够好用并且简单,但对于 Spring 官方主推的安全框架 Spring Security,用户群也是甚大的,所以我们这 ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十五):Spring Security 版本

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro ...

  5. Spring Security 快速上手

    Spring Security 框架简介 Spring Security 说明 Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案 关于安全方面的两 ...

  6. Spring Security基于Oauth2的SSO单点登录怎样做?一个注解搞定

    一.说明 单点登录顾名思义就是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统,免除多次登录的烦恼.本文主要介绍 同域 和 跨域 两种不同场景单点登录的实现原理,并使用 Spring ...

  7. spring security 在controller层 方法级别使用注解 @PreAuthorize("hasRole('ROLE_xxx')")设置权限拦截 ,无权限则返回403

    1.前言 以前学习的时候使用权限的拦截,一般都是对路径进行拦截 ,要么用拦截器设置拦截信息,要么是在配置文件内设置拦截信息, spring security 支持使用注解的形式 ,写在方法和接口上拦截 ...

  8. Spring Security OAuth2 开发指南

    官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...

  9. SPRING SECURITY JAVA配置:Web Security

    在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...

随机推荐

  1. machine learning学习笔记

    看到Max Welling教授主页上有不少学习notes,收藏一下吧,其最近出版了一本书呢还,还没看过. http://www.ics.uci.edu/~welling/classnotes/clas ...

  2. Login用户登录(Python实现)

    username_fault = "isuperSun" #程序存储用户名和密码 password_fault = " counts = 0 while counts&l ...

  3. java自定义泛型 面试题:接收任意数组进行反转 泛型通配符

    不用泛型只能操作某种类型进行反转 代码如下: package com.swift.fanxing; import org.junit.Test; public class RenyiReverse { ...

  4. 谈谈对bug的一点想法,说说做好日志记录的重要性

    说起程序猿,总绕不开的一个话题就是bug,估计每个程序猿听到某某测试跑过来一脸淫笑的告诉你这个功能有个bug的时候,总有种恨不得掐死他的想法.其实程序猿跟bug的关系,感觉有点像父亲和儿子的关系,自己 ...

  5. python-读写文件的方式

    open(path, flag[, encoding][, errors]) path:要打开文件的路径 flag:打开方式 r 以只读的方式打开文件,文件的描述符放在文件的开头 rb 以二进制格式打 ...

  6. Thinkphp 取消Url默认模块的现实

    例子http://www.tp.com/home/index/index 想要现实的效果是:http://www.tp.com/index/index 1是通过配置路由来达到目的 2通过配置首页的入口 ...

  7. 40.VUE学习之--组件之间的数据传参父组件向子组件里传参,props的使用实例操作

    父组件向子组件里传参,props的使用实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...

  8. 选择排序算法Java实现

    一. 算法描述 选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1 ...

  9. [Bzoj3894]文理分科(最小割)

    Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...

  10. spark streaming的应用

    今天我们讲spark streaming的应用,这个是实时处理的,类似于Storm以及Flink相关的知识点, 说来也巧,今天的自己也去听了关于Flink的相关的讲座,可惜自己没有听得特别清楚,好像是 ...