首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

依据web提交的过滤器链

2012-07-01 
根据web提交的过滤器链spring security从2.0开始,在配置文件中只需配置一个security:http命名空间就可以

根据web提交的过滤器链
spring security从2.0开始,在配置文件中只需配置一个<security:http>命名空间就可以代表一个FilterChainProxy过滤器链,而不用明确的配置出。
org.springframework.security.web.FilterChainProxy维持了一个过滤器链,并用一个currentPosition控制依次执行以下过滤器(spring security3.0.7)。


org.springframework.security.web.session.ConcurrentSessionFilter,
处理session并发。首先判断该访问对应的session是不是第一次访问,如果是第一次访问则SessionInformation为null则过滤链向下进行,如果不是第一次访问则判断此session的标记是不是已过期如果过期则执行推出操作,如果未过期则更行session的访问时间过滤链继续执行。
这个过滤器执行两个方法。首先,它对所有的请求调用org.springframework.security.core.session.SessionRegistry的refreshLastRequest(sessionId)方法,更新已经创建的session的最后请求的时间。然后为每个请求从SessionRegistry重新得到org.springframework.security.core.session.SessionInformation,然后判断这个session是否已经到期。如果已经到期,则会调用org.springframework.security.web.authentication.logout.LogoutFilter销毁这个session,然后重定向一个session无效的URL。这个类主要是判断session是否失效。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)            throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) req;        HttpServletResponse response = (HttpServletResponse) res;        HttpSession session = request.getSession(false);        if (session != null) {            SessionInformation info = sessionRegistry.getSessionInformation(session.getId());            if (info != null) {                if (info.isExpired()) {                    // Expired - abort processing                    doLogout(request, response);                    String targetUrl = determineExpiredUrl(request, info);                    if (targetUrl != null) {                        redirectStrategy.sendRedirect(request, response, targetUrl);                        return;                    } else {                        response.getWriter().print("This session has been expired (possibly due to multiple concurrent " +                                "logins being attempted as the same user).");                        response.flushBuffer();                    }                    return;                } else {                    // Non-expired - update last request date/time                    sessionRegistry.refreshLastRequest(info.getSessionId());                }            }        }        chain.doFilter(request, response);



org.springframework.security.web.context.SecurityContextPersistenceFilter
FILTER_APPLIED属性用于确保此过滤器每次访问只执行一次。此类用于每次过滤器链执行时提供一个SecurityContext放入SecurityContextHolder进行验证。
在请求到来之前从SecurityContextRepository获得SecurityContext存到SecurityContextHolder之中。在请求完毕或清空context holder时再存回SecurityContext仓库。默认是使用一个HttpSessionSecurityContextRepository。这个过滤器在每一次请求只执行一次,解决servlet容器的兼容(特别是Weblogic)。
这个过滤器必须在所有的认证处理机制前执行。因为认证处理机制(BASIC、CAS处理过滤器等)执行时会认为SecurityContextHolder包含一个有效的SecurityContext。
forceEagerSessionCreation属性用于去确定一个session在过滤器链执行前都是可用的。默认是false,因为这是资源密集型的,不推荐

org.springframework.security.web.authentication.logout.LogoutFilter
判断请求rui是不是以j_spring_security_logout结尾,如果是的话就调用logouthandle进行退出操作。一系列的LogoutHandler进行投票,这些投票的顺序应该被规定的。通常需要调用TokenBasedRememberMeServices和SecurityContextLogoutHandler。当退出成功后,根据构造方法调用LogoutSuccessHandler或logoutSuccessUrl进行重定向。

org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
此类继承于org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter这个抽象认证处理过滤器类用于处理基于HTTP浏览器的请求认证。
这个抽象类需要判定请求的uri是不是以j_spring_security_check结尾,如果是的话就进行认证处理,如果不是的话就往下执行。
UsernamePasswordAuthenticationFilter的attemptAuthentication()方法用户认证处理,并且不支持POST提交认证。
将获得的用户名和密码封装为一个org.springframework.security.authentication.UsernamePasswordAuthenticationToken类,此类是Authentication的一个子类,用于将用户名和密码进行简单的封装。然后将用户名存于session中,其key是SPRING_SECURITY_LAST_USERNAME
调用authenticationManager(org.springframework.security.authentication. ProviderManager)中调用配置文件中的认证管理器进行认证。


处理表单提交认证。在spring security3.0是调用AuthenticationProcessingFilter
登录表单必须向此过滤器提供两个参数:用户名和密码。默认的用户名和密码的名字在SPRING_SECURITY_FORM_USERNAME_KEY和SPRING_SECURITY_FORM_PASSWORD_KEY 设定好了。可以通过usernameParameter和passwordParameter修改。
这个过滤器默认对URL(/j_spring_security_check)响应。


org.springframework.security.web.authentication.www.BasicAuthenticationFilter

表单登录此过滤器不执行。

org.springframework.security.web.savedrequest.RequestCacheAwareFilter
在RequestCache查找是否有已存储的和此次访问相同的request如果有则把存储的request传入doFilter方法。

org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
这个过滤器通过一个被包装的request构成ServletRequest。org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper中根据传入的角色前缀验证request中的Authentication有没有角色访问权限

org.springframework.security.web.authentication.AnonymousAuthenticationFilter
匿名登录过滤器,检查SecurityContextHolder中有没有Authentication,如果没有则创建一个AnonymousAuthenticationToken。
org.springframework.security.web.session.SessionManagementFilter
检查访问开始时此用户是否已被授权,如果已被授权则执行session相关的激活,比如并发登录。

org.springframework.security.web.access.ExceptionTranslationFilter
处理过滤器链中所有的拒绝访问异常和认证异常。这个过滤器是java异常和http 响应之间的一个桥梁,它是唯一和维护用户接口有关的。这个过滤器不执行任何和安全相关的处理。如果一个认证异常被探测到。这个过滤器将加载authenticationEntryPoint,这将处理任何从org.springframework.security.access.intercept.AbstractSecurityInterceptor子类的认证异常。
如果拒绝访问异常被检查到。过滤器将检查这个用户是不是匿名用户。如果是个匿名用户则加载authenticationEntryPoint。如果不是匿名用户,过滤器将转到org.springframework.security.web.access.AccessDeniedHandler默认是加载org.springframework.security.web.access.AccessDeniedHandlerImpl


org.springframework.security.web.access.intercept.FilterSecurityInterceptor

调用org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource进行验证。这个类并不会执行到验证的行就被返回了。所以这个类实质上并没有进行验证。



热点排行