zoukankan      html  css  js  c++  java
  • Spring Security 04

    转至:Elim的博客http://elim.iteye.com/blog/2161648

    Filter Porxy

    DelegatingFilterProxy

    DelegationFilterProxy不是spring security的入口,它其实是spring的一个代理类(org.springframework.web.filter.DelegatingFilterProxy),作用是将spring 与 spring security融合。
    它内部代理的是spring scurity的FilterChainProxy(org.springframework.security.web.FilterChainProxy)代理类。真正执行工作的是是FilterChainProxy。FilterChainProxy中会加载
    所有的spring security filter,然后调用每个Filter的doFilter方法。targetFilterLifecycle初始化为true时,会调用所有filer的init初始化方法
    详情查看https://www.cnblogs.com/hzhuxin/archive/2011/12/19/2293730.html

    <filter>
      <filter-name>springSecurityFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    
      <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>  <!-- 默认是false -->
        </init-param>
     </filter>
    
    <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
    
     </filter-mapping>
    

    FilterChainProxy

    Spring security允许我们在配置文件中配置多个http元素,以针对不同形式的URL使用不同的安全控制。Spring Security将会为每一个http元素创建对应的FilterChain,同时按照它们的声明顺序加入到FilterChainProxy。所以当我们同时定义多个http元素时要确保将更具有特性的URL配置在前。

    <security:http pattern="/login*.jsp*" security="none"/>
    
       <!-- http元素的pattern属性指定当前的http对应的FilterChain将匹配哪些URL,如未指定将匹配所有的请求 -->
    
       <security:http pattern="/admin/**">
    
          <security:intercept-url pattern="/**" access="ROLE_ADMIN"/>
    
       </security:http>
    
       <security:http>
    
          <security:intercept-url pattern="/**" access="ROLE_USER"/>
    
       </security:http>
    

    需要注意的是http拥有一个匹配URL的pattern,未指定时表示匹配所有的请求,其下的子元素intercept-url也有一个匹配URL的pattern,该pattern是在http元素对应pattern基础上的,也就是说一个请求必须先满足http对应的pattern才有可能满足其下intercept-url对应的pattern。

    Filter Chain中的Filer,按照先后顺序

    • ChannelProcessingFilter,如果你访问的channel错了,那首先就会在channel之间进行跳转,如http变为https。

    • SecurityContextPersistenceFilter,这样的话在一开始进行request的时候就可以在SecurityContextHolder中建立一个SecurityContext,然后在请求结束的时候,任何对SecurityContext的改变都可以被copy到HttpSession。

    • ConcurrentSessionFilter,因为它需要使用SecurityContextHolder的功能,而且更新对应session的最后更新时间,以及通过SessionRegistry获取当前的SessionInformation以检查当前的session是否已经过期,过期则会调用LogoutHandler。

    • 认证处理机制,如UsernamePasswordAuthenticationFilter,CasAuthenticationFilter,BasicAuthenticationFilter等,以至于SecurityContextHolder可以被更新为包含一个有效的Authentication请求。

    • SecurityContextHolderAwareRequestFilter,它将会把HttpServletRequest封装成一个继承自HttpServletRequestWrapper的SecurityContextHolderAwareRequestWrapper,同时使用SecurityContext实现了HttpServletRequest中与安全相关的方法。

    • JaasApiIntegrationFilter,如果SecurityContextHolder中拥有的Authentication是一个JaasAuthenticationToken,那么该Filter将使用包含在JaasAuthenticationToken中的Subject继续执行FilterChain。

    • RememberMeAuthenticationFilter,如果之前的认证处理机制没有更新SecurityContextHolder,并且用户请求包含了一个Remember-Me对应的cookie,那么一个对应的Authentication将会设给SecurityContextHolder。

    • AnonymousAuthenticationFilter,如果之前的认证机制都没有更新SecurityContextHolder拥有的Authentication,那么一个AnonymousAuthenticationToken将会设给SecurityContextHolder。

    • ExceptionTransactionFilter,用于处理在FilterChain范围内抛出的AccessDeniedException和AuthenticationException,并把它们转换为对应的Http错误码返回或者对应的页面。

    • FilterSecurityInterceptor,保护Web URI,并且在访问被拒绝时抛出异常。

    自定义Filter,并添加到FilterChain

    使用NameSpace时添加Filter到FilterChain是通过http元素下的custom-filter元素来定义的。定义custom-filter时需要我们通过ref属性指定其对应关联的是哪个Filter,此外还需要通过position、before或者after指定该Filter放置的位置。eg:position=”CAS_FILTER”就表示将定义的Filter放在CAS_FILTER对应的那个位置

    Filter别名

    别名 Filter类 对应元素或属性
    CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channe
    SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http
    CONCURRENT_SESSION_FILTER ConcurrentSessionFilter http/session-management/concurrency-control
    LOGOUT_FILTER LogoutFilter http/logout
    X509_FILTER X509AuthenticationFilter http/x509
    PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter 的子类
    CAS_FILTER CasAuthenticationFilter
    FORM_LOGIN_FILTER UsernamePasswordAuthenticationFilter http/form-login
    BASIC_AUTH_FILTER BasicAuthenticationFilter http/http-basic
    SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter http@servlet-api-provision
    JAAS_API_SUPPORT_FILTER JaasApiIntegrationFilter http@jaas-api-provision
    REMEMBER_ME_FILTER RememberMeAuthenticationFilter http/remember-me
    ANONYMOUS_FILTER AnonymousAuthenticationFilter http/anonymous
    SESSION_MANAGEMENT_FILTER SessionManagementFilter http/session-managemen
    EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
    FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
    SWITCH_USER_FILTER SwitchUserFilter

    Spring Security定义好的核心Filter

    FilterSecurityInterceptor

    FilterSecurityInterceptor是用于保护Http资源的,它需要一个AccessDecisionManager和一个AuthenticationManager的引用。它会从SecurityContextHolder获取Authentication,然后通过SecurityMetadataSource可以得知当前请求是否在请求受保护的资源。对于请求那些受保护的资源,如果Authentication.isAuthenticated()返回false或者FilterSecurityInterceptor的alwaysReauthenticate属性为true,那么将会使用其引用的AuthenticationManager再认证一次,认证之后再使用认证后的Authentication替换SecurityContextHolder中拥有的那个。然后就是利用AccessDecisionManager进行权限的检查。
    我们在使用基于NameSpace的配置时所配置的intercept-url就会跟FilterChain内部的FilterSecurityInterceptor绑定。如果要自己定义FilterSecurityInterceptor对应的bean,那么该bean定义大致如下所示:

    <bean id="filterSecurityInterceptor"
    
       class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    
          <property name="authenticationManager" ref="authenticationManager" />
    
          <property name="accessDecisionManager" ref="accessDecisionManager" />
    
          <property name="securityMetadataSource">
    
             <security:filter-security-metadata-source>
    
                <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
    
                <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN" />
    
             </security:filter-security-metadata-source>
    
          </property>
    
       </bean>
    

    filter-security-metadata-source用于配置其securityMetadataSource属性。intercept-url用于配置需要拦截的URL与对应的权限关系。

    ExceptionTranslationFilter

    通过前面的介绍我们知道在Spring Security的Filter链表中ExceptionTranslationFilter就放在FilterSecurityInterceptor的前面。而ExceptionTranslationFilter是捕获来自FilterChain的异常,并对这些异常做处理。ExceptionTranslationFilter能够捕获来自FilterChain所有的异常,但是它只会处理两类异常,AuthenticationException和AccessDeniedException,其它的异常它会继续抛出。如果捕获到的是AuthenticationException,那么将会使用其对应的AuthenticationEntryPoint的commence()处理。如果捕获的异常是一个AccessDeniedException,那么将视当前访问的用户是否已经登录认证做不同的处理,如果未登录,则会使用关联的AuthenticationEntryPoint的commence()方法进行处理,否则将使用关联的AccessDeniedHandler的handle()方法进行处理。
    AuthenticationEntryPoint是在用户没有登录时用于引导用户进行登录认证的,在实际应用中应根据具体的认证机制选择对应的AuthenticationEntryPoint。
    AccessDeniedHandler用于在用户已经登录了,但是访问了其自身没有权限的资源时做出对应的处理。ExceptionTranslationFilter拥有的AccessDeniedHandler默认是AccessDeniedHandlerImpl,其会返回一个403错误码到客户端。我们可以通过显示的配置AccessDeniedHandlerImpl,同时给其指定一个errorPage使其可以返回对应的错误页面。当然我们也可以实现自己的AccessDeniedHandler。

    <bean id="exceptionTranslationFilter"
          class="org.springframework.security.web.access.ExceptionTranslationFilter">
          <property name="authenticationEntryPoint">
             <bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
                <property name="loginFormUrl" value="/login.jsp" />
             </bean>
          </property>
          <property name="accessDeniedHandler">
             <bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
                <property name="errorPage" value="/access_denied.jsp" />
             </bean>
          </property>
       </bean>
    

    在上述配置中我们指定了AccessDeniedHandler为AccessDeniedHandlerImpl,同时为其指定了errorPage,这样发生AccessDeniedException后将转到对应的errorPage上。指定了AuthenticationEntryPoint为使用表单登录的LoginUrlAuthenticationEntryPoint。此外,需要注意的是如果该filter是作为自定义filter加入到由NameSpace自动建立的FilterChain中时需把它放在内置的ExceptionTranslationFilter后面,否则异常都将被内置的ExceptionTranslationFilter所捕获。

  • 相关阅读:
    ironic port bind
    pdb /usr/bin/neutron-server
    networking_generic_switch
    [CodeForces586D]Phillip and Trains
    [CodeForces598D]Igor In the Museum
    [poj3468]A Simple Problem with Integers
    [bzoj1503][NOI2004]郁闷的出纳员
    [bzoj1208][HNOI2004]宠物收养所
    [luogu3384][模板]树链剖分
    [CodeForces869A]The Artful Expedient
  • 原文地址:https://www.cnblogs.com/nwu-edu/p/9425473.html
Copyright © 2011-2022 走看看