实现机制
概括来讲,是将认证信息放在Session中,当客户端发起访问时检查Session中是否存在认证信息,以及认证信息中的权限是否满足预期。
更具体地说,是通过Filter来拦截客户端请求并进行判断处理,使用的Filter链如下:
[
org.springframework.security.web.context.SecurityContextPersistenceFilter,
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter,
org.springframework.security.web.header.HeaderWriterFilter,
org.springframework.security.web.authentication.logout.LogoutFilter,
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter,
org.springframework.security.web.authentication.www.BasicAuthenticationFilter,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter,
org.springframework.security.web.session.SessionManagementFilter,
org.springframework.security.web.access.ExceptionTranslationFilter,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor
]
值得注意的是:这些Filter都是Spring Security框架中定义的,它们会被加载到Spring容器中,最终会被包装到FilterChainProxy$.VirtualFilterChain
的additionalFilters
属性中。
那么这些Filter是如何生效的呢?
与普通的Sevlet Filter不同,这些Filter不需要在web.xml中明确配置,但是需要在web.xml中配置org.springframework.web.filter.DelegatingFilterProxy
作为进入Spring Security框架的入口。
<!-- 集成Spring Security框架 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
DelegatingFilterProxy
的执行路径如下:
org.springframework.web.filter.DelegatingFilterProxy.doFilter()
->org.springframework.security.web.FilterChainProxy.doFilter() -> doFilterInternal()
->org.springframework.security.web.FilterChainProxy$.VirtualFilterChain.doFilter()
最后是在org.springframework.security.web.FilterChainProxy$.VirtualFilterChain.doFilter()
方法中依次取出additionalFilters
属性中的Filter对象执行拦截操作。
认证流程
如上所述,Spring Security的认证实现都是通过Filter拦截来实现的,最终是在org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication()
方法中实现的。
具体的执行流程图如下:
默认情况下,Spring Security处理登录认证的URI地址为/login
,且只支持POST
方法,这可以从UsernamePasswordAuthenticationFilter
的构造函数中得到确认。
public UsernamePasswordAuthenticationFilter() {
super(new AntPathRequestMatcher("/login", "POST"));
}
也就是说在<security:form-login>
中指定的login-processing-url
属性实际上必须是/login
,同时也必须把自定义登录页面表单中的action
属性也设置为login
。
当然,Spring Security处理登录认证的URI地址是可以修改的,如下所示在<security:form-login>
中修改:
<!--授权自定义登录页-->
<security:form-login login-processing-url="/lg">
特别注意:如果修改了默认认证地址URI,则必须同步修改自定义登录页面表单中的action
属性值。
【参考】
java笔记----springMvc简单整合spring-security示例