接口报405啥原因(接口报403是为什么)

接口报405啥原因(接口报403是为什么)Spring Security 是为基于 Spring 的应用程序提供声明式安全保护的安全性框架 Spring Security 提供了完整的安全性解决方案 它能够在 Web 请求级别和方法调用级别处理身份认证和授权 因为基于 Spring 框架 所以 Spring Security 充分利用了依赖注入 dependency injection DI 和面向切面 AOP 的技术 认证 以手机必装 APP 微信为例 在初次使用微信前需要注册成为微信用户 然后输入账号和密码即可登录微信




Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架。Spring Security提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权。因为基于Spring框架,所以Spring Security充分利用了依赖注入(dependency injection,DI)和面向切面(AOP)的技术。

认证

以手机必装APP微信为例,在初次使用微信前需要注册成为微信用户,然后输入账号和密码即可登录微信,输入账号和密码登录微信的过程就是认证。

系统为什么要认证?

认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源。用户认证就是判断一个用户的身份是否合法的过程,用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问,不合法则拒绝访问。常见的用户身份认证方式有:用户名密码登录,二维码登录,手机短信登录,指纹认证等方式。

会话

用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于session方式、基于token方式等。

基于session的认证方式如下图:

接入spring secuity 禁用了csrf但所有请求依然403_访问控制

它的交互流程是,用户认证成功后,在服务端生成用户相关的数据保存在(当前会话)中,发给客户端的存放到中,这样用户客户端请求时带上就可以验证服务器端是否存在数据,以此完成用户的合法校验,当用户退出系统或过期销毁时,客户端的也就无效了。

基于token方式如下图:

接入spring secuity 禁用了csrf但所有请求依然403_java_02

它的交互流程是,用户认证成功后,服务端生成一个token发给客户端,客户端可以放到或等存储中,每次请求时带上,服务端收到通过验证后即可确认用户身份。

基于的认证方式由规范定制,服务端存储信息需要占用内存资源,客户端需要支持;基于的方式则一般不需要服务端存储,并且不限制客户端的存储方式。如今移动互联网时代更多类型的客户端需要接入系统,系统多是采用前后端分离的架构进行实现,所以基于的方式更适合。

授权

微信登录成功后用户即可使用微信的功能,比如,发红包、发朋友圈、添加好友等,没有绑定银行卡的用户是无法发送红包的,绑定银行卡的用户才可以发红包,发红包功能、发朋友圈功能都是微信的资源即功能资源,用户拥有发红包功能的权限才可以正常使用发送红包功能,拥有发朋友圈功能的权限才可以使用发朋友圈功能,这个根据用户的权限来控制用户使用资源的过程就是授权。

为什么要授权?

认证是为了保证用户身份的合法性,授权则是为了更细粒度的对隐私数据进行划分,授权是在认证通过后发生的,控制不同的用户能够访问不同的资源。

授权是用户认证通过根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问。

授权的数据模型

授权可简单理解为WhoWhat(which)进行How操作:

  • Who,即主体(Subject),主体一般是指用户,也可以是程序,需要访问系统中的资源。
  • What,即资源(Resource),如系统菜单、页面、按钮、代码方法、系统商品信息、系统订单信息等。系统菜单、页面、按钮、代码方法都属于系统功能资源,对于web系统每个功能资源通常对应一个URL;系统商品信息、系统订单信息都属于实体资源(数据资源),实体资源由资源类型和资源实例组成,比如商品信息为资源类型,商品编号为001的商品为资源实例。
  • How,权限/许可(Permission),规定了用户对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个代码方法的调用权限、编号为001的用户的修改权限等,通过权限可知用户对哪些资源都有哪些操作许可。

主体、资源、权限关系如下图:

接入spring secuity 禁用了csrf但所有请求依然403_访问控制_03

我们一般并不会直接对主体授权,而是在主体和权限之间引入了角色的概念,让主体和权限解耦,使得配置更灵活。设计的数据模型如下图:

接入spring secuity 禁用了csrf但所有请求依然403_spring_04

  • 主体(用户id、账号、密码、…)
  • 角色(角色id、角色名称、…)
  • 权限(权限id、权限标识、权限名称、资源id、…)
  • 资源(资源id、资源名称、访问地址、…)
  • 主体(用户)和角色关系(用户id、角色id、…)
  • 角色和权限关系(角色id、权限id、…)

通常企业开发中将资源和权限表合并为一张权限表:

  • 资源(资源id、资源名称、访问地址、…)
  • 权限(权限id、权限标识、权限名称、资源id、…)

合并为:

  • 权限(权限id、权限标识、权限名称、资源名称、资源访问地址、…)

修改后数据模型之间的关系如下图:

接入spring secuity 禁用了csrf但所有请求依然403_ide_05

RBAC

基于角色的访问控制

RBAC基于角色的访问控制(Role-Based Access Control)是按角色进行授权,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如下:


接入spring secuity 禁用了csrf但所有请求依然403_spring_06

根据上图中的判断逻辑,授权代码可表示如下:

如果上图中查询工资所需要的角色变化为总经理和部门经理,此时就需要修改判断逻辑为“判断用户的角色是否是总经理或部门经理”,修改代码如下:

根据上边的例子发现,当需要修改角色的权限时就需要修改授权的相关代码,系统可扩展性差。

基于资源的访问控制

RBAC基于资源的访问控制(Resource-Based Access Control)是按资源(或权限)进行授权,比如:用户必须具有查询工资权限才可以查询员工工资信息等,访问控制流程如下:

接入spring secuity 禁用了csrf但所有请求依然403_数据库_07

根据上图中的判断,授权代码可以表示为:

优点:系统设计时定义好查询工资的权限标识,即使查询工资所需要的角色变化为总经理和部门经理也不需要修改授权代码,系统可扩展性强

介绍

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统中的一员,因此它伴随着整个Spring生态系统不断修正、升级,在spring boot项目中加入Spring Security更是十分简单,使用Spring Security 减少了为企业系统安全控制编写大量重复代码的工作。

Spring Boot是一套Spring的快速开发框架,基于Spring 4.0设计,使用Spring Boot开发可以避免一些繁琐的工程搭建和配置,同时它集成了大量的常用框架,快速导入依赖包,避免依赖包的冲突。我们将采用Spring Boot提供的spring-boot-starter-security依赖包开发Spring Security应用。

创建工程

创建maven工程,工程结构如下:

接入spring secuity 禁用了csrf但所有请求依然403_ide_08

引入依赖

SpringBoot配置

SpringBoot工程启动会自动扫描启动类所在包下的所有Bean,加载到spring容器。

Spring Boot配置文件

在resources下添加,内容如下:

Spring Boot 启动类

认证页面

Spring Security默认提供认证页面,不需要额外开发。由于Spring boot starter自动装配机制,我们只需指定一个包含注解的配置类即可,在中添加默认请求根路径跳转到,此url为spring security提供。

Spring Security提供的默认登录页面:

接入spring secuity 禁用了csrf但所有请求依然403_spring_09

Spring Security提供的默认登出页面为:

接入spring secuity 禁用了csrf但所有请求依然403_java_10

安全配置

Spring Security提供了用户名密码登录、退出、会话管理等认证功能,只需要配置即可使用。

在包下定义,安全配置的内容包括:用户信息、密码编码器、安全拦截机制。

在方法中,我们返回了一个给spring容器,Spring Security会使用它来获取用户信息。我们暂时使用实现类,并在其中分别创建了、两个用户,并设置密码和权限。

在方法中,我们通过HttpSecurity设置了安全拦截规则,其中包含了以下内容:

  1. url匹配/r/**的资源,经过认证后才能访问。
  2. 其他url完全开放。
  3. 授权:访问/r/r1资源的 url需要拥有p1权限,访问/r/r2资源的 url需要拥有p2权限.
  4. 支持form表单认证,认证成功后转向/login-success。

更多关于HttpSecurity的配置可参考附录:HttpSecurity配置列表

测试

创建一个控制器类:

经测试我们可以发现,在没有登录的情况下访问url或者会跳转到登录页,访问非开头的url比如会提示404错误。我们可以用账号和密码或者和密码进行登录,输入其他会提示账号密码错误。在登录后,可以正常访问,访问会提示403错误。

结构总览

Spring Security所解决的问题就是安全访问控制,而安全访问控制功能其实就是对所有进入系统的请求进行拦截,校验每个请求是否能够访问它所期望的资源。Spring Security对Web资源的保护是靠Filter实现的,当初始化Spring Security时,会创建一个名为的Servlet过滤器,类型为,它实现了,因此外部的请求会经过此类,Spring Security过滤器链结构图:

接入spring secuity 禁用了csrf但所有请求依然403_数据库_11

FilterChainProxy是一个代理,真正起作用的是FilterChainProxy中SecurityFilterChain所包含的各个Filter,同时这些Filter作为Bean被Spring管理,它们是Spring Security核心,各有各的职责,但他们并不直接处理用户的认证,也不直接处理用户的授权,而是把它们交给了认证管理器(AuthenticationManager)和决策管理器(AccessDecisionManager)进行处理,下图是FilterChainProxy相关类的UML图示:

接入spring secuity 禁用了csrf但所有请求依然403_spring_12

Spring Security功能的实现主要是由一系列过滤器链相互配合完成。

接入spring secuity 禁用了csrf但所有请求依然403_数据库_13


过滤器链中几个主要的过滤器及其作用:

  • SecurityContextPersistenceFilter 这个Filter是整个拦截过程的入口和出口(也就是第一个和最后一个拦截器),会在请求开始时从配置好的中获取,然后把它设置给。在请求完成后将持有的再保存到配置好的,同时清除 所持有的;
  • UsernamePasswordAuthenticationFilter 用于处理来自表单提交的认证。该表单必须提供对应的用户名和密码,其内部还有登录成功或失败后进行处理的和 ,这些都可以根据需求做相关改变;
  • FilterSecurityInterceptor 是用于保护web资源的,使用对当前用户进行授权访问;
  • ExceptionTranslationFilter 能够捕获来自所有的异常并进行处理。但是它只会处理两类异常:和,其它的异常它会继续抛出

认证流程

接入spring secuity 禁用了csrf但所有请求依然403_java_14

  1. 用户提交用户名、密码被SecurityFilterChain中的过滤器获取到,封装为请求,通常情况下是这个实现类;
  2. 然后过滤器将提交至认证管理器进行认证 ;
  3. 认证成功后,认证管理器返回一个被填充满了信息(包括上面提到的权限信息,身份信息,细节信息,但密码通常会被移除)的实例。
  4. 安全上下文容器将第3步填充了信息的,通过方法,设置到其中。

可以看出接口(认证管理器)是认证相关的核心接口,也是发起认证的出发点,它的实现类为。而Spring Security支持多种认证方式,因此维护着一个 列表,存放多种认证方式,最终实际的认证工作是由完成的。例如web表单的对应的实现类为,它的内部又维护着一个负责UserDetails的获取。最终将填充至。

认证核心组件的大体关系如下:

接入spring secuity 禁用了csrf但所有请求依然403_数据库_15

AuthenticationProvider

认证管理器(AuthenticationManager)委托完成认证工作。是一个接口,定义如下:

方法定义了认证的实现过程,它的参数是一个,里面包含了登录用户所提交的用户、密码等。而返回值也是一个,这个Authentication则是在认证成功后,将用户的权限及其他信息重新组装后生成。

Spring Security中维护着一个列表,存放多种认证方式,不同的认证方式使用不同的。如使用用户名密码登录时,使用AuthenticationProvider1,短信登录时使用AuthenticationProvider2等等这样的例子很多。

每个AuthenticationProvider需要实现方法来表明自己支持的认证方式,如我们使用表单方式认证,在提交请求时Spring Security会生成,它是一个Authentication,里面封装着用户提交的用户名、密码信息。那么对应的,哪个会来处理它?

我们在的基类发现以下代码:

也就是说当web表单提交用户名密码时,将由处理认证。

最后,我们来看一下(认证信息)的结构,它是一个接口,我们之前提到的就是它的实现之一:

UserDetailsService

我们已经知道DaoAuthenticationProvider处理web表单的认证逻辑,认证成功后即得到一个Authentication(UsernamePasswordAuthenticationToken实现),里面包含了身份信息(Principal)。这个身份信息就是一个Object ,大多数情况下它可以被强转为对象。 DaoAuthenticationProvider中包含了一个实例,它负责根据用户名提取用户信息UserDetails(包含密码),而后DaoAuthenticationProvider会去对比提取的用户密码与用户提交的密码是否匹配作为认证成功的关键依据,因此可以通过将自定义的公开为spring bean来定义自定义身份验证。

很多人可能会把和的职责搞混淆,其实只负责从特定的地方(通常是数据库)加载用户信息,仅此而已。而DaoAuthenticationProvider的职责更大,它完成完整的认证流程,同时会把UserDetails填充至Authentication。

是用户信息,它的接口定义如下:

它和接口很类似,比如它们都拥有username,authorities。的与中的需要被区分对待,前者是用户提交的密码凭证,后者是用户实际存储的密码,认证其实就是对这两者的比对。中的实际是由的传递而形成的。还记得接口中的方法吗?其中的用户详细信息便是经过了认证之后被填充的。

通过实现和,我们可以完成对用户信息获取方式以及用户信息字段的扩展。 Spring Security提供的(内存认证),(jdbc认证)就是UserDetailsService的实现类,主要区别无非就是从内存还是从数据库加载用户。

创建一个自定义的实现类:

屏蔽掉原先安全配置类中的定义:

启动工程,测试登录,的方法被调用 ,查询用户信息。

PasswordEncoder

认证处理器通过UserDetailsService获取到UserDetails后,它是如何与请求中的密码做对比呢?在这里Spring Security为了适应多种多样的加密类型又做了抽象,通过接口的方法进行密码的对比,而具体的密码对比细节取决于实现:

Spring Security提供很多内置的,能够开箱即用,使用某种只需要进行如下声明即可,如下:

采用字符串匹配方法,不对密码进行加密比较处理,密码比较流程如下:

  1. 用户输入密码(明文 )
  2. DaoAuthenticationProvider获取UserDetails(其中存储了用户的正确密码)
  3. DaoAuthenticationProvider使用PasswordEncoder对输入的密码和正确的密码进行校验,密码一致则校验通过,否则校验失败

实际项目中推荐使用, , 等,感兴趣的大家可以看看这些PasswordEncoder的具体实现。

以使用为例,修改安全配置类的密码编码器:

添加测试类,对登录密码进行加密

添加SpringBoot测试依赖:

编写测试方法:

修改安全配置类,将UserDetails中的原始密码修改为BCrypt格式:

实际项目中存储在数据库中的密码并不是原始密码,都是经过加密处理的密码。

授权流程

通过前面快速上手的例子我们知道,Spring Security可以通过对web请求进行授权保护。Spring Security使用标准Filter建立了对web请求的拦截,最终实现对资源的授权访问。Spring Security的授权流程如下:

接入spring secuity 禁用了csrf但所有请求依然403_ide_16

拦截请求,已认证用户访问受保护的web资源将被SecurityFilterChain中的的子类拦截;

获取资源访问策略,会从的子类获取要访问当前资源所需要的权限。其实就是读取访问策略的抽象,而读取的内容,其实就是我们配置的访问规则, 读取访问策略如

授权决策,最后,会调用进行授权决策,若决策通过,则允许访问资源,否则将禁止访问。

(访问决策管理器)的核心接口如下:

这里着重说明一下decide的参数:

  • authentication:要访问资源的访问者的身份
  • object:要访问的受保护资源,web请求对应FilterInvocation
  • configAttributes:是受保护资源的访问策略,通过SecurityMetadataSource获取。

decide接口就是用来鉴定当前用户是否有访问对应受保护资源的权限。

授权决策

采用投票的方式来确定是否能够访问受保护资源。

接入spring secuity 禁用了csrf但所有请求依然403_数据库_17

通过上图可以看出,中包含的一系列将会被用来对是否有权访问受保护对象进行投票,根据投票结果,做出最终决策。

是一个接口,其中定义有三个方法,具体结构如下所示:

方法的返回结果会是AccessDecisionVoter中定义的三个常量之一。表示同意,表示拒绝,表示弃权。如果一个AccessDecisionVoter不能判定当前Authentication是否拥有访问对应受保护对象的权限,则其方法的返回值应当为弃权。

Spring Security内置了三个基于投票的AccessDecisionManager实现类:

AffirmativeBased的逻辑是:

  1. 只要有的投票为则同意用户进行访问;
  2. 如果全部弃权也表示通过;
  3. 如果没有一个人投赞成票,但是有人投反对票,则将抛出。

Spring security默认使用的是。

ConsensusBased的逻辑是:

  1. 如果赞成票多于反对票则表示通过;
  2. 反过来,如果反对票多于赞成票则将抛出;
  3. 如果赞成票与反对票相同且不等于0,并且属性的值为true,则表示通过,否则将抛出异常。参数的值默认为true;
  4. 如果所有的AccessDecisionVoter都弃权了,则将视参数的值而定,如果该值为true则表示通过,否则将抛出异常。参数的值默认为false。

UnanimousBased的逻辑与另外两种实现有点不一样,另外两种会一次性把受保护对象的配置属性全部传递给AccessDecisionVoter进行投票,而会一次只传递一个ConfigAttribute给AccessDecisionVoter进行投票。这也就意味着如果我们的AccessDecisionVoter的逻辑是只要传递进来的ConfigAttribute中有一个能够匹配则投赞成票,但是放到UnanimousBased中其投票结果就不一定是赞成了。UnanimousBased的逻辑具体来说是这样的:

  1. 如果受保护对象配置的某一个ConfigAttribute被任意的AccessDecisionVoter反对了,则将抛出;
  2. 如果没有反对票,但是有赞成票,则表示通过;
  3. 如果全部弃权了,则将视参数allowIfAllAbstainDecisions的值而定,true则通过,false则抛出。

Spring Security也内置一些投票者实现类如、和等。

Spring Security提供了非常好的认证扩展方法,比如快速上手中将用户信息存储到内存中,实际开发中用户信息通常在数据库,Spring security可以实现从数据库读取用户信息,Spring Security还支持多种授权方法。

自定义登录页面

快速上手中,你可能会想知道登录页面从哪里来的?因为我们并没有提供任何的HTML或JSP文件。Spring Security的默认配置没有明确设定一个登录页面的URL,因此Spring Security会根据启用的功能自动生成一个登录页面URL,并使用默认URL处理登录的提交内容,登录后跳转的到默认URL等等。尽管自动生成的登录页面很方便快速启动和运行,但大多数应用程序都希望定义自己的登录页面。

在快速上手工程中创建登录页面login.jsp,目录结构如下:

接入spring secuity 禁用了csrf但所有请求依然403_访问控制_18

由于是在SpringBoot项目中创建jsp文件,需在项目属性中配置web资源文件夹路径,这里指向我们刚刚创建的webapp文件夹:

接入spring secuity 禁用了csrf但所有请求依然403_spring_19


login.jsp内容如下:

添加jsp依赖,修改porm.xml文件:

在文件中添加如下信息:

在WebConfig.java中配置认证页面地址:

在安全配置中配置表单登录信息:

测试:当用户没有认证时访问系统的资源会重定向到login-view页面

接入spring secuity 禁用了csrf但所有请求依然403_访问控制_20

输入账号和密码,点击登录,报错:

接入spring secuity 禁用了csrf但所有请求依然403_spring_21

问题原因:

spring security为防止CSRF(Cross-site request forgery跨站请求伪造)的发生,限制了除了get以外的大多数方法。

解决方法1:

屏蔽CSRF控制,即spring security不再限制CSRF。 配置WebSecurityConfig:

解决方法2:

在login.jsp页面添加一个token,spring security会验证token,如果token合法则可以继续请求。修改login.jsp:

本案例我们采用解决方案1。

连接数据库认证

前边的例子我们是将用户信息存储在内存中,实际项目中用户信息存储在数据库中,根据前边对认证流程研究,只需要重新定义UserDetailService即可实现根据用户账号查询数据库。

创建数据库

代码实现

在配置mysql连接信息:

添加数据库访问依赖:

定义模型类型,在model包定义UserDto:

在Dao包定义UserDao:

在service包下定义SpringDataUserDetailsService:

注意:如果我们采用的是的密码编码器,数据库中也应该存储的是用此加密的密码。

用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。spring security提供会话管理,认证通过后将身份信息放入上下文,SecurityContext与当前线程进行绑定,方便获取用户身份。

获取用户身份

Spring Security获取当前登录用户信息的方法为,我们可以在LoginController中定义一个方法:

会话控制

我们可以通过以下选项准确控制会话何时创建以及Spring Security如何与之交互:

接入spring secuity 禁用了csrf但所有请求依然403_数据库_22

通过修改安全配置类对该选项进行配置:

默认情况下,Spring Security会为每个登录成功的用户会新建一个Session,就是ifRequired

若选用never,则指示Spring Security对登录成功的用户不创建Session了,但若你的应用程序在某地方新建了session,那么Spring Security会用它的。

若使用stateless,则说明Spring Security对登录成功的用户不会创建Session了,你的应用程序也不会允许新建session,并且它会暗示不使用cookie,所以每个请求都需要重新进行身份验证。这种无状态架构适用于REST API及其无状态认证机制。

会话超时

可以再sevlet容器中设置Session的超时时间,比如设置Session有效期为3600秒,修改spring boot配置文件:

session超时之后,可以通过Spring Security设置跳转的路径:

invalidSession指传入的sessionid无效,expired指session过期,maximumSessions指最大session并发数,比如当有2个admin账号登录时,前一个登录的admin账号session会失效。

安全会话cookie

我们可以使用httpOnly和secure标签来保护我们的会话cookie,修改spring boot配置文件:

前面说过spring security默认实现了logout退出页面,我们也可以自定义退出成功的页面,以及退出登录的行为。

当退出操作出发时,将发生:

  • 使HTTP Session无效
  • 清除 SecurityContextHolder
  • 跳转到

注意:如果让logout在GET请求下生效,必须关闭防止CSRF攻击。如果开启了CSRF必须使用post方式请求logout。

logoutHandler

一般来说,的实现类被用来执行必要的清理,因而他们不应该抛出异常。

下面是Spring Security提供的一些实现:

  • PersistentTokenBasedRememberMeServices 基于持久化token的RememberMe功能的相关清理
  • TokenBasedRememberMeService 基于token的RememberMe功能的相关清理
  • CookieClearingLogoutHandler 退出时Cookie的相关清理
  • CsrfLogoutHandler 负责在退出时移除csrfToken
  • SecurityContextLogoutHandler 退出时SecurityContext的相关清理

授权的方式包括 web授权和方法授权,web授权是通过url拦截进行授权,方法授权是通过方法拦截进行授权。它们都会调用accessDecisionManager进行授权决策,若为web授权则拦截器为;若为方法授权则拦截器为。如果同时通过web授权和方法授权则先执行web授权,再执行方法授权,最后决策通过,则允许访问资源,否则将禁止访问。 类关系如下:

接入spring secuity 禁用了csrf但所有请求依然403_访问控制_23

环境配置

在我们之前创建的数据库中执行如下脚本:

在UserDao中添加根据用户id查询用户权限方法:

修改UserDetailService,实现从数据库读取权限:

Web授权

前面例子中我们已经完成了对URL的认证拦截,我们可以通过给添加多个子节点实现灵活的授权控制,以定制需求到我们的URL。

保护URL常用的方法有:

  • authenticated() 保护URL,需要用户登录
  • permitAll() 指定URL无需保护,一般应用与静态资源文件
  • hasRole(String role) 限制单个角色访问,角色将被增加 “ROLE_” .所以”ADMIN” 将和 “ROLE_ADMIN”进行比较.
  • hasAuthority(String authority) 限制单个权限访问
  • hasAnyRole(String… roles)允许多个角色访问
  • hasAnyAuthority(String… authorities) 允许多个权限访问
  • access(String attribute) 该方法使用 SpEL表达式, 所以可以创建复杂的限制
  • hasIpAddress(String ipaddressExpression) 限制IP地址或子网

注意规则的顺序是重要的,更具体的规则应该先写。因为一旦前面的规则匹配上,后面的规则会忽略。比如如果将放置到最前面的话,那么资源r1、r2、r3因满足的匹配条件,不会再去验证权限。

方法授权

我们已经知道如何使用对web资源进行授权保护,从Spring Security2.0版本开始,它支持服务层方法的安全性的支持,通过,, 这三类注解实现方法授权。

我们可以在任何实例上使用注释来启用基于注解的安全性。如以下内容将启用Spring Security的注解:

然后向方法(在类或接口上)添加注解就会限制对该方法的访问。Spring Security的原生注释支持为该方法定义了一组属性,这些将被传递给AccessDecisionManager以供它作出实际的决定:

以上配置标明、方法可匿名访问,底层使用投票器,方法需要有TELLER角色才能访问,底层使用RoleVoter投票器。

和声明权限的格式一样,区别是前者在方法执行之前拦截,后者在方法执行之后拦截。使用如下代码可启用prePost注解的支持:

相应Java代码如下:

以上配置标明、方法可匿名访问,方法需要同时拥有和权限才能访问,底层使用投票器。

使用注解后,可以移除安全配置中的设置访问控制的代码,如果方法不包含授权注解,则方法可以不受限制的访问。

编程小号
上一篇 2025-03-22 18:46
下一篇 2025-03-09 11:40

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/8148.html