【第八章】Spring Security基于URL权限控制

我想我是太过依赖,在挂电话的刚才,坚持学单纯的小孩,静静看守这份爱。

一、基于URL的权限控制

前面几个章节,我们对Spring Security的原理已经大概了解了,这个章节我们基于原理聊聊Spring Security的权限控制,首先我们聊聊基于URL的权限控制。

1.1 配置

首先我们看下我们的初始配置:
在这里插入图片描述
我们已经知道了,当前这个配置对所有请求都需要认证通过才放行,因此当我现在访问我定义的接口/hello时是自动重定向到默认的登录页面的,那么基于URL的权限控制我们现在需要放行/hello请求不需要认证,就需要增加下面的配置:
在这里插入图片描述
然后我们再次访问/hello将不需要认证了:
在这里插入图片描述

1.2 原理解读

那么authorize.antMatchers(“/hello”).permitAll()做了什么能够让我们不需要认证就能通过了,其实前面的原理解读中都又讲解过,小伙伴们可以自己先尝试通过源码看下原因。

下面我们将再次通过源码看一下,当作是一个回顾加深理解,后面将不再这么详细说明这块的内容了。

  1. 首先我们看下http.authorizeHttpRequests()做了什么:
    在这里插入图片描述
    这个方法的入参是一个泛型为AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry的Customizer接口实现类对象,这个方法里创建了一个AuthorizeHttpRequestsConfigurer配置器。配置器我们已经很熟悉了,Spring Security的配置过程就是通过各种配置器完成的,Spring Security的这中设计方式我们可以多看多思考,看看是否能有所借鉴的,好了,多余的话不多说。看下配置器的构造方法:
    在这里插入图片描述
    构造器里我们主要关注这个AuthorizationManagerRequestMatcherRegistry注册器,这里知道配置器的registry属性值为AuthorizationManagerRequestMatcherRegistry类型的对象,好了,回到HttpSecurity的authorizeHttpRequests方法中,我们看到创建了AuthorizeHttpRequestsConfigurer配置器后,调用了getRegistry()方法,在这里插入图片描述
    返回的就是AuthorizationManagerRequestMatcherRegistry。我么看一下这个类:
    在这里插入图片描述
    他是继承自AbstractRequestMatcherRegistry抽象类,并且泛型为AuthorizedUrl,基本了解之后我们继续往下。

  2. antMatchers()方法

下面我们进入antMatchers()方法:
在这里插入图片描述
我们已经知道了,这个方法的返回类型C为AuthorizedUrl,好,继续看RequestMatchers.antMatchers(antPatterns):
在这里插入图片描述
在这里插入图片描述
我们看到返回的是一个存储AntPathRequestMatcher的集合,由我们传入的/hello可以知道,返回的集合只有一个元素,且匹配的url为/hello。然后进入chainRequestMatchers方法:
在这里插入图片描述

这里将AuthorizationManagerRequestMatcherRegistry中的unmappedMatchers属性赋值,并返回一个AuthorizedUrl实列对象。然后我们进入permitAll方法:
在这里插入图片描述
这里的permitAllAuthorizationManager变量值我们看下:
在这里插入图片描述
这里我们记好,这个AuthorizationManager对象在判定是否放行时将直接返回已授权放行的。回到上面继续往下:
在这里插入图片描述
addMapping方法入参第一个是匹配我们/hello路径的匹配器,第二个是判定直接返回true的授权管理器,我们跟下去:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时我们AuthorizeHttpRequestsConfigurer配置器中的注册表AuthorizationManagerRequestMatcherRegistry中的managerBuilder变量值可以确定了是RequestMatcherDelegatingAuthorizationManager委托请求匹配授权管理器的建造器对象,并且这个builder建造器中的请求映射是有了我们定义的/hello路径以及对应的授权管理器的。那么最终我们的配置器在执行配置方法时会通过这个建造器构造出委托请求匹配授权管理器:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
并且最终传入AuthorizationFilter过滤器的构造方法中:
在这里插入图片描述

  1. 最终判定
    在AuthorizationFilter过滤器的最终判定时:
    在这里插入图片描述
    在这里插入图片描述
    最终对于/hello路径返回可以放行,因此此时我们的/hello路径将不需要认证了。

1.3 加入角色控制

对于我们当前的配置我们看到使用了permitAll()和authenticated(),permitAll是创建了一个始终返回true的授权管理器,而authenticated创建了一个需要校验凭证的授权管理器,那么还有没有其他的的授权管理器呢?

答案是有的,首先我们不管是antMatchers还是anyRequest方法返回的都是一个AuthorizedUrl对象,那么我们看下AuthorizedUrl类中的方法:
在这里插入图片描述
可以看到除了permitAll和authenticated还有可以通过通过角色、权限来控制访问,我们知道最终的AuthorizationFilter进行判定是否放行是通过授权管理器完成的,而在AuthorizedUrl中控制访问的方法中都是通过创建授权管理器AuthorizationManager接口的实现类来实现不同方式的控制,前面我们已经看过了两个,下面我们再来看看通过角色、权限控制的方法中创建的授权管理器实现类,我们先看hasRole方法:
在这里插入图片描述
入参是我们传入的角色字符串,继续往下:
在这里插入图片描述
这里注意一下,我们在传入角色的时候都是直接传入USER、ADMIN这样的,Spring Security在这里会给我们加上默认前缀"ROLE_"的,在跟下去:
在这里插入图片描述
其实到这里,我们可以停下来注意看下这个hasAuthority方法,大家可以退会AuthorizedUrl类中看看另一种权限控制的方法hasAuthority,跟进去会发现也会调用上面的方法,因此,使用hasRole和hasAuthority方法效果是一样的,不同点在于hasRole方法不需要我们传入前缀,Spring Security会给我们默认加上前缀,而hasAuthority方法则不会给我们加前缀。好了,言归正传,上面的方法会返回AuthorizationManager接口的另一个实现类AuthorityAuthorizationManager:
在这里插入图片描述
至于授权管理器在过滤器中何时调用我们就不再重复了,我们直接看这个类中判定是否放行的check方法:
在这里插入图片描述
我们可以看到,是通过判断凭证中的权限是否包含在我们定义的权限中来决定是否放行的,那么凭证中的权限是哪里定义的呢,前面几个章节阅读过的小伙伴应该都知道了,在UserDetailService中我们定义了:
在这里插入图片描述

1.4 定义基于角色的权限控制

通过上面的阅读,我们应该有一个思路应该如何配置了,下面我们来尝试一下:
在这里插入图片描述
首先/hello需要USER角色,/admin需要ADMIN角色,我们的用户只有USER角色,下面启动项目后访问看结果:
在这里插入图片描述
在这里插入图片描述
可以看到/hello可以访问,而/admin返回了访问拒绝了,到这里基于角色的访问控制就实现了,当然从我们前面的讲解中,可以灵活的进行配置,比如:
在这里插入图片描述
要注意,在定义User时,roles和authorities方法不能同时使用,后面会覆盖前面的,大家可以自己跟进源码看看就明白了。
到这里基于URL的权限控制我们就基本聊完了,大家可以自己去多看多尝试,这里额外补充一点,既然我们说最终判定是否放行请求的判定时通过不同的AuthorizationManager接口的实现类来实现的,那我们可不可以自己实现一个呢?通过上面的源码解读,大家有没有自己的思路可以先停下来思考一下。

1.5 自定义权限控制

好了,大家应该注意到,不管上面我们是hasRole,hasAuthority或者authenticated,他们最终调用的都是AuthorizedUrl类中的access方法,而access方法的入参就是AuthorizationManager对象,那么我们通过自定义一个AuthorizationManager接口的实现类,然后在antMatchers方法后面直接调用access方法,传入我们定义的AuthorizationManager对象是不是就可以了,下面我们来试一下:
在这里插入图片描述
在这里插入图片描述
通过上面的方式就实现了自定义访问控制了。

总结:这里的逻辑还是比较绕的,建议小伙伴们静下心来多看看,理清逻辑,就能明白这里的原理了,同时这里面还有更多的配置方式,大家有兴趣的可以登录spring官网去了解,我们这里谈的基本都是大家比较常用的。

未完待续~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值