背景
链接:https://segmentfault.com/a/1190000012668936
spring security框架的过滤器是基于基础的filter来实现,这样它可以不需要依赖任何web框架,甚至连spring mvc框架都不需要依赖,这样整个spring security过滤器就会变得异常的轻量级和无侵入性。
spring security处理请求流程
用户发起请求,认证管理器(Authentication Manager)会发起拦截,验证用户发起请求时的一些凭证信息,未通过验证信息审核的那么返回给用户,通过审核的,那么继续进行请求访问,访问页面之前,会被访问决策管理(Access Decision Manager)拦截,访问决策管理器验证用户是否有访问页面的权限,如果有,那么继续到访问页面。
另外spring security是通过委托代理(delegates)的方式去实现过滤器链的,
首先先通过过滤器拦截用户的请求,拦截后通过servlet来进行处理,如果处理成功那么进行正常访问,在返回给用户一个请求。
1.security.xml配置
(1) 配置一些不需要安全验证即可登录的资源:
<http pattern="/login.html" security="none"/>
(2)认证管理器,也就是确认用户名密码是否正确。
<authentication-manager erase-credentials="false" alias="authenticationManager">
<authentication-provider ref="customUserDetailService">
<!-- 如果用户的密码采用加密的话,可以加点“盐” <password-encoder hash="md5" /> -->
</authentication-provider>
</authentication-manager>
<!-- 自定义用户服务,读取用户表信息进行登录验证,这个类 -->
<b:bean id="customUserDetailService" class="cn.topcheer.common.authority.springsec.CustomUserDetailService">
</b:bean>
(3)配置收到HTTP请求时的安全验证配置:
<!--http 标签属性中定义了 登录点,认证类,访问控制类-->
<http auto-config="false" entry-point-ref="authenticationEntryPoint" authentication-manager-ref="authenticationManager" access-decision-manager-ref="customAccessDecisionManager">
<csrf disabled="true"></csrf>
<logout success-handler-ref="logoutSuccessHandler"></logout>
<!-- 一部分允许所有用户访问的.do后台资源在此配置,AccessDecisionManage不再进行权限验证 -->
<intercept-url pattern="/admin/**" access="ROLE_ADMIN"></intercept-url>
<intercept-url pattern="/user/getCurrentUser.do" access="permitAll"></intercept-url>
<!-- 其他所有资源要求进行访问权限验证 -->
<intercept-url pattern="/**" access="isAuthenticated()"></intercept-url>
<!--自定义实现用户名密码及验证码判断功能的Filter-->
<custom-filter ref="customUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
<anonymous enabled="false"></anonymous>
</http>
其中可以自定义实现功能的<b:bean>,比如“自定义实现用户名及密码验证判断功能的Filter”,它将class文件注入,
<!--自定义实现用户名密码及验证码判断功能的Filter,因为用户认证模块涉及了验证码,所以单独写了一个filter,这里这个类就只起了比对用户密码的功能 -->
<b:bean id="customUsernamePasswordAuthenticationFilter" class="cn.topcheer.common.authority.springsec.CustomUsernamePasswordAuthenticationFilter">
<b:property name="enableValidateCode" value="false"></b:property>
<b:property name="authenticationManager" ref="authenticationManager"></b:property>
<b:property name="authenticationFailureHandler" ref="failureHandler"></b:property>
<b:property name="authenticationSuccessHandler" ref="successHandler"></b:property>
</b:bean>
其中,<b:property>定义的是该类属性,<b:constuctor-arg></b:constructor-arg>是该类的构造方法;
(4)用户自定义过滤器
设定格式形如:
<custom-filter ref="customUsernamePasswordAuthenticationFilter" position="过滤器假名"/>
” position”表示本过滤器,要替代其后的过滤器. "过滤器假名"指示了被替代的过滤器名; 除了” position”,还有”before” 与”after”两种方式。
分别表示将要把本过滤器挂在其后的过滤器前或后。
标准过滤器假名和顺序
假名 过滤器类
CHANNEL_FILTER ChannelProcessingFilter
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter
SESSION_CONTEXT_INTEGRATION_FILTER HttpSessionContextIntegrationFilter
LOGOUT_FILTER LogoutFilter
X509_FILTER X509PreAuthenticatedProcessigFilter
PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter Subclasses
CAS_PROCESSING_FILTER CasProcessingFilter
AUTHENTICATION_PROCESSING_FILTER AuthenticationProcessingFilter
BASIC_PROCESSING_FILTER BasicProcessingFilter
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter
REMEMBER_ME_FILTER RememberMeProcessingFilter
ANONYMOUS_FILTER AnonymousProcessingFilter
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter
NTLM_FILTER NtlmProcessingFilter
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor
SWITCH_USER_FILTER SwitchUserProcessingFilter
1、ChannelProcessingFilter,使用它因为我们可能会指向不同的协议(如:Http,Https)
2、SecurityContextPersistenceFilter,负责从SecurityContextRepository 获取或存储 SecurityContext。SecurityContext 代表了用户安全和认证过的session
3、ConcurrentSessionFilter,使用SecurityContextHolder的功能,更新来自“安全对象”不间断的请求,进而更新SessionRegistry
4、认证进行机制,UsernamePasswordAuthenticationFilter,CasAuthenticationFilter,BasicAuthenticationFilter等等--SecurityContextHolder可能会修改含有Authentication这样认证信息的token值
5、SecurityContextHolderAwareRequestFilter,如果你想用它的话,需要初始化spring security中的HttpServletRequestWrapper到你的servlet容器中。
6、JaasApiIntegrationFilter,如果JaasAuthenticationToken在SecurityContextHolder的上下文中,在过滤器链中JaasAuthenticationToken将作为一个对象。
7、RememberMeAuthenticationFilter,如果还没有新的认证程序机制更新SecurityContextHolder,并且请求已经被一个“记住我”的服务替代,那么将会有一个Authentication对象将存放到这(就是 已经作为cookie请求的内容)。
8、AnonymousAuthenticationFilter,如果没有任何认证程序机制更新SecurityContextHolder,一个匿名的对象将存放到这。
9、ExceptionTranslationFilter,为了捕获spring security的错误,所以一个http响应将返回一个Exception或是触发AuthenticationEntryPoint。
10、FilterSecurityInterceptor,当连接被拒绝时,保护web URLS并且抛出异常。