SpringSecurity的认证实现分析

实现机制

概括来讲,是将认证信息放在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$.VirtualFilterChainadditionalFilters属性中。

那么这些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()方法中实现的。
具体的执行流程图如下:
SpringSecurity登录认证流程

默认情况下,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示例

posted @ 2024-03-22 22:52  nuccch  阅读(17)  评论(0编辑  收藏  举报