spring-security(十八)核心Filter-FilterSecurityInterceptor

前言:
当用spring security时,我们会用到各种各样的filter,在接下来的章节中我们我们将着重讨论几个核心的Filter,本节将讨论FilterSecurityInterceptor这个filter。
和这个类相关的对象如下图所示
[img]http://dl2.iteye.com/upload/attachment/0128/9716/26917b9a-17ba-3202-9103-503dcb506b64.png[/img]
一、FilterSecurityInterceptor功能和属性
1.FilterSecurityInterceptor的主要职责是处理http资源的安全性。从上面的关系图中,可以知道这个类中主要有以下属性
[list]
[*]AuthenticationManager-认证
[*]AccessDecisionManager-鉴权
[*]SecurityMetadataSource-获取属性列表
[*]RunAsManager-替换认证用户
[*]AfterInvocationManager-鉴权完成后续处理
[/list]
上面的属性会在下面三个主要的方法中被使用到
[list]
[*]beforeInvocation
[*]finallyInvocation
[*]afterInvocation
[/list]
1.1.beforeInvocation方法
这个方法是最主要的方法,我们的权限判断逻辑主要在这个方法里进行,主要执行下面几步逻辑
[list]
[*]调用SecurityMetadataSource(实际执行时spring boot为我们装配的实例是ExpressionBasedFilterInvocationSecurityMetadataSource,可以通过FilterSecurityInterceptor.setSecurityMetadataSource方法修改)来获取匹配当前请求的ConfigAttribute列表,如果获取的列表为null并且rejectPublicInvocations属性配置的是true(不允许存在不受保护的调用),则直接抛出异常,否则鉴权处理结束,如果不为null,执行下一步,因为ExpressionBasedFilterInvocationSecurityMetadataSource在获取当前request相匹配的ConfigAttribute列表时是按照定义的顺序来查找的,一旦找到匹配的就直接返回,所有越具体的匹配规则应配置的越靠前
[*]判断SecurityContextHolder中是否包含Authentication对象,如果没有,就是说程序执行到这个鉴权的filter了却还没有认证过,直接抛出AuthenticationException异常,如果有Authentication,执行下一步
[*]判断alwaysReauthenticate的值,如果设置成true,即所有请求在鉴权前都需要重新认证,则会调用AuthenticationManager(实际执行时是ProviderManager实例)的authenticate方法,进行具体的再认证过程,并把认证结果放入SecurityContextHolder中。
[*]接着调用AccessDecisionManager(默认情况下是AffirmativeBased实例)decide方法,传入Authentication对象、当前的安全对象、以及对应的ConfigAttribute列表开始鉴权,在鉴权过程中如果发生AccessDeniedException,发布鉴权异常事件并抛出异常
[*]如果配置了RunAsManager(在有些特殊场合下,如我们的业务层的某个方法中需要访问外部系统,需要我们提供一个不同的证书,我们可以配置这个RunAsManager,将当前认证过的用户替换成外部系统需要的认证者,之后spring security会自动把安全证书传递到外部系统中,默认是NullRunAsManager即不需要转换用户),则对用户进行转换,将转换后的用户存入SecurityContextHolder中,放回一个InterceptorStatusToken,否则直接返回InterceptorStatusToken对象
[/list]
另外说下FilterSecurityInterceptor的securityMetadataSource属性实际定义的是SecurityMetadataSource的子类FilterInvocationSecurityMetadataSource,这个接口是一个标记接口,里面没有方法,仅仅说明用这个接口的实现类知道传入的安全对象是一个FilterInvocation,并能从里面获取到request,

public Collection<ConfigAttribute> getAttributes(Object object) {
final HttpServletRequest request = ((FilterInvocation) object).getRequest();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry:requestMap
.entrySet()) {
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值