spring security 是构建在一系列filter之上的,这些filter会拦截请求,检测身份信息并将其重定向到身份认证组件或者授权组件,我自己常用的是UsernamePasswordAuthenticationFilter + AuthenticManager + 真正的调用提供者Provider。每一个Filter都要有AuthenticManager ,从而可以用其调用authenticate方法,进而找到ProviderManager 中的Provider 的authenticate方法进行调用。
//Filter类
this.getAuthenticationManager().authenticate(authRequest);
结果就是要么被后端接口执行,要么抛出相关异常(认证不通过、权限不够)。
最终要的是 WebSecurityConfigureAdapter类该类作为一个抽象类,自己的配置类通过继承他来配置信息。比如UserDetailService 用来定义数据库获取操作以及根据用户名查到的用户所具有的权限。Provider是自定义认证逻辑,Filer 定义其过滤链中的位置、其失败处理器和成功处理器。一般配置的Filter有FilterSercurityInteceptor (自定义的)用来实现。
重要的Filter FilterSercurityInteceptor主要是做鉴权的工作,其中FilterSecurityInterceptor 过滤器是通过对url的拦截,从而首先获得调用(SecurityMetaSource自定义类)得到此路径(资源)相关的权限,然后可以调用AccessDecisionManager 来对该请求进行判断。从而决定抛出异常还是,放行访问对应的API.
最后还有一些资源路径的配置,比如哪些是不需要认证与鉴权的,哪些是需要的。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
/*add */
auth.authenticationProvider(getCustomUsernamePasswordAuthenticationProvider());
}
spring security 主要做认证和授权两部分工作。
在我们配置好认证需要的UsernameService(从数据库中获取用户 ) 和 AuthenticationProvider(主要做认证工作) 之后,在用户登陆时,我们会拦截到其http请求,得到用户名和密码然后创建未认证的token 去 认证管理器认证,它会选择我们定义的AuthenticationProvider去进行认证工作,从而返回结果。如果成功则 调用成功处理器 AuthenticationSuccessHandler,失败则调用失败处理器。认证成功之后其认证信息就被框架记录下来,在之后的访问中就需要对其鉴权。
鉴权时候 首先得到对应URL 的角色信息,然后调用decisionMannager 来进行鉴权,我们现在有该url需要的角色信息,有框架缓存的认证信息 该认证信息里面有其角色信息,那么只需要一比对,如果认证信息的角色 在 需要的角色里面 则权限验证通过,否则权限验证失败,调用AccessDeniedHandler 进行处理。
2021 9 4 日更新
spring security 主要用于权限设计,对用户进行认证,对url进行授权。spring security 是基于过滤器的,即函数回调,SecurityFilterChain 默认有十几个过滤器,同时我们也可在webSecurityConfig 配置文件中添加自己的过滤器到过滤器链中从而实现功能 ,过滤器有SecurityContextPersistFilter 主要是用来 获取SercurityContext 放置在ThreadLocal中,同时在请求完成后清除ThreadLocal中的SercurityContext ,将其放在session中。(每一个客户端用户会对应一个session 放置在服务端的ConcurrentHashMap 中(sessionId,session)) 还有usernamePasswordFilter 用来进行账户名和把密码的认证。认证成功之后将Authentication设置在ThreadLocal的securityContext中。 FilterSecurityInteceptor主要是对进行鉴权的工作,首先需要从数据库中获取url->权限表,然后从ThreadLocal中获取context中的认证成功后的Authentication,之后便可以通过decissionManager进行decide 到底有没有权限,如果authentication中的url和将要访问的url匹配之后判断 权限是否匹配,如果匹配则放行,否则通知无权限。
spring secuirty 通过过滤器 功能划分明确,并且方便扩展。
WebSecurityConfiguration 生成 名为springSecurityFilterChain 类型为FilterChainProxy(实现了FIlter 接口)的 bean,该bean 只是作为 代理,所有请求都会经过该bean,真正起作用的是该类中的一个个FilterChain 。每个FilterChain中的Filter 各有各的职责。但是他们并不是直接处理用户的认证和授权,而是交给AuthenticationManager 和AccessDecisionManager 进行管理。
AuthenticationManager 主要是认证工作,ProviderManager 是其实现类,其内部维护了AuthenticationProvider 列表做认证工作。认证失败则抛出异常 认证成功则进行后续的操作。