無極,無際,無跡

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            3 Posts :: 8 Stories :: 10 Comments :: 0 Trackbacks
          接著來。
          2.過濾器的配置:
            我們已經配置了那些過濾器了,但是要跟spring context中的對象對應,于是乎,做了如下配置:
            <beans:bean id="securityContextPersistenceFilter"
                    class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
            </beans:bean>
            <beans:bean id="logoutFilter"
                    class="org.springframework.security.web.authentication.logout.LogoutFilter" >
                    <beans:constructor-arg type="java.lang.String" value="/"/>
                    <beans:constructor-arg ref="securityContextLogoutHandler"/>
            </beans:bean>
            <beans:bean id="basicAuthenticationFilter"
                    class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
                    <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
                    <beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"></beans:property>
            </beans:bean>
            <beans:bean id="requestCacheAwareFilter"
                    class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter">
            </beans:bean>
            <beans:bean id="securityContextHolderAwareRequestFilter"
                    class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
            </beans:bean>
            <beans:bean id="anonymousAuthenticationFilter"
                    class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
                    <beans:property name="userAttribute" ref="anonymousUserAttribute"></beans:property>
                    <beans:property name="key"      value="anonymousUser"/>
            </beans:bean>
            <beans:bean id="sessionManagementFilter"
                    class="org.springframework.security.web.session.SessionManagementFilter">
                    <beans:constructor-arg  type="org.springframework.security.web.context.SecurityContextRepository" ref="sessionSecurityContextRepository"/>
            </beans:bean>
            <beans:bean id="exceptionTranslationFilter"
                    class="org.springframework.security.web.access.ExceptionTranslationFilter">
                    <beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/>
            </beans:bean>
            <beans:bean id="filterSecurityInterceptor"
                    class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
                    <beans:property name="authenticationManager"  ref="authenticationManager" />
                    <beans:property name="accessDecisionManager"  ref="accessDecisionManager" />
                    <beans:property name="securityMetadataSource" ref="securityMetadataSource" />
            </beans:bean>
           
            <!-- The following beans are configured for the filters upstairs -->
            <!-- ///////////////////////////////////////// -->
            <!-- ////for LogoutFilter///////////////////// -->
            <!-- ///////////////////////////////////////// -->
            <beans:bean id="securityContextLogoutHandler"
                    class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
            </beans:bean>
            <!-- ///////////////////////////////////////// -->
            <!-- ////for AnonymousAuthenticationFilter//// -->
            <!-- ///////////////////////////////////////// -->
            <beans:bean id="anonymousUserAttribute"
                    class="org.springframework.security.core.userdetails.memory.UserAttribute">
                    <beans:property name="authorities">
                      <beans:list>
                         <beans:ref  bean="anonymousUserGrantedAuthority" />
                      </beans:list>
                    </beans:property>
                    <beans:property name="password" value="anonymousUser"/>
            </beans:bean>
            <beans:bean id="anonymousUserGrantedAuthority"
                    class="org.springframework.security.core.authority.GrantedAuthorityImpl">
                    <beans:constructor-arg type="java.lang.String" value="ROLE_ANONYMOUS"/>
            </beans:bean>
            <!-- ///////////////////////////////////////// -->
            <!-- ////for SessionManagementFilter////////// -->
            <!-- ///////////////////////////////////////// -->
            <beans:bean id="sessionSecurityContextRepository"
                    class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
            </beans:bean>
            <!-- ///////////////////////////////////////// -->
            <!-- ////for FilterSecurityInterceptor//////// -->
            <!-- ///////////////////////////////////////// -->
            <beans:bean id="accessDecisionManager"
                    class="org.springframework.security.access.vote.AffirmativeBased">
                    <beans:property name="decisionVoters">
                      <beans:list>
                         <beans:ref bean="webExpressionVoter"/>
                      </beans:list>
                    </beans:property>
            </beans:bean>
            <beans:bean id="webExpressionVoter"
                    class="com.saveworld.authentication.web.access.expression.MyWebExpressionVoter">
            </beans:bean>
            <beans:bean id="securityMetadataSource"
                    class="com.saveworld.authentication.web.access.intercept.MyFilterInvocationSecurityMetadataSource">
                    <beans:constructor-arg type="org.springframework.security.web.util.UrlMatcher" ref="urlMatcher" />
                    <beans:constructor-arg type="javax.sql.DataSource" ref="proxoolDataSource" />
                    <beans:constructor-arg type="org.springframework.security.web.access.expression.WebSecurityExpressionHandler"
                                               ref="expressionHandler" />
            </beans:bean>
            <beans:bean id="urlMatcher"
                    class="org.springframework.security.web.util.AntUrlPathMatcher" >
                    <beans:constructor-arg type="boolean" value="true" />
            </beans:bean>
            <beans:bean id="expressionHandler"
                    class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
            </beans:bean>
          這里做幾點說明:
             (1) 數據庫中的權限相關的表:
                      ROLES
                      AUTHORITIES
                      USER_AUTHS
                      ROLE_AUTHS
                      USERS
                 這里的表結構還不是最終的,所以就不發上來誤導兄弟姐妹們了。
                 關鍵是看我們如何加載這些持久化的東西。
                 這個就要看看filterSecurityInterceptor了,它里面使用了一個securityMetadataSource,本地的securityMetadataSource實現代碼:
                public class MyFilterInvocationSecurityMetadataSource extends DefaultFilterInvocationSecurityMetadataSource{
              private final static Log logger = LogFactory.getLog(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
              private DataSource datasource;
             
              public MyFilterInvocationSecurityMetadataSource(UrlMatcher urlMatcher,
                                                              DataSource datasource,
                                                              WebSecurityExpressionHandler expressionHandler) {
                  super(urlMatcher, processMap(initializeFromDb(datasource,null),expressionHandler.getExpressionParser()));
              }

              //This method is usefulless for now!
              //Because this method is used for parsing the expression kind
              private static LinkedHashMap<RequestKey, Collection<ConfigAttribute>> processMap(
                      LinkedHashMap<RequestKey,Collection<ConfigAttribute>> requestMap, ExpressionParser parser) {
                  Assert.notNull(parser, "SecurityExpressionHandler returned a null parser object");

                  LinkedHashMap<RequestKey, Collection<ConfigAttribute>> requestToExpressionAttributesMap =
                      new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>(requestMap);

                  for (Map.Entry<RequestKey, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {
                      RequestKey request = entry.getKey();
                      Assert.isTrue(entry.getValue().size() == 1, "Expected a single expression attribute for " + request);
                      ArrayList<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>(1);
                      String expression = entry.getValue().toArray(new ConfigAttribute[1])[0].getAttribute();
                      logger.debug("Adding web access control expression '" + expression + "', for " + request);
                      try {
                          //Replacing WebExpressionConfigAttribute with MyWebExpressionConfigAttribute
                          //which is defined locally!
                          attributes.add(new MyWebExpressionConfigAttribute(parser.parseExpression(expression)));
                      } catch (ParseException e) {
                          throw new IllegalArgumentException("Failed to parse expression '" + expression + "'");
                      }

                      requestToExpressionAttributesMap.put(request, attributes);
                  }

                  return requestToExpressionAttributesMap;
              }

              private static LinkedHashMap<RequestKey,Collection<ConfigAttribute>> initializeFromDb(DataSource datasource,LinkedHashMap<RequestKey, Collection<ConfigAttribute>> configMap){
                  LinkedHashMap<RequestKey,Collection<ConfigAttribute>> result =
                      new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
                  Connection conn = null;
                  Statement  stmt = null;
                  ResultSet  rs   = null;
                  try {
                      conn = datasource.getConnection();
                      stmt = conn.createStatement();
                      StringBuilder sql = new StringBuilder("SELECT b.AUTHORITYPATTERN ,'hasRole('||chr(39)||a.ROLENAME||chr(39)||')' rolename ")
                                                       .append(" FROM ROLES a,AUTHORITIES b,ROLE_AUTHS c ")
                                                       .append(" WHERE a.rolename = c.rolename AND b.authorityname = c.authorityname");
                     
                      rs = stmt.executeQuery(sql.toString());
                      String roles = "";
                      RequestKey key = null;
                      List<ConfigAttribute> value = null;
                      while(rs != null && rs.next()){
                          key = new RequestKey(rs.getString(1));
                          roles = rs.getString(2);
                          String[] roleArray = roles.split(",|\\s+|;");
                          value = new ArrayList<ConfigAttribute>();
                          for(String role : roleArray){
                              ConfigAttribute config = new SecurityConfig(role);
                              value.add(config);
                          }
                          result.put(key, value);
                      }
                      //just for test
                  } catch (SQLException e) {
                      e.printStackTrace();
                  } finally{
                      try{
                          rs.close();
                          stmt.close();
                          conn.close();
                      }catch(SQLException e){
                          e.printStackTrace();
                      }
                  }
                  return result;
              }
             
             
             
              public boolean supports(Class<?> clazz) {
                  return FilterInvocation.class.isAssignableFrom(clazz);
              }

              public DataSource getDatasource() {
                  return datasource;
              }

              public void setDatasource(DataSource datasource) {
                  this.datasource = datasource;
              }
          }
           (2) expressionHandler:
               這個東西要單獨說說,我這里用的是表達式來檢測用戶角色的,所以,我用org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler來處理了,還有其他的方式,就是直接用角色進行判斷,那樣會更好,這里就不描述了!


          posted on 2010-01-25 16:29 taochen 閱讀(2309) 評論(4)  編輯  收藏 所屬分類: java設計模式軟件架構

          Feedback

          # re: SpringSecurity使用記錄(六)-- 本地配置二 2010-07-12 11:46 kcai678
          樓主,
          能否將“com.saveworld.authentication.web.access.expression.MyWebExpressionVoter”的代碼貼出來參考參考,謝謝。

            回復  更多評論
            

          # re: SpringSecurity使用記錄(六)-- 本地配置二 2010-09-09 17:30 taochen1984
          @kcai678
          好久沒看郵件了,還望諒解

          不過我的這個類沒有多少特別之處,就是把那個WebExpressionVoter類轉換成我的類了
          然后在配置文件中配置了一下  回復  更多評論
            

          # re: SpringSecurity使用記錄(六)-- 本地配置二 2010-09-09 17:35 taochen1984
          @kcai678
          package com.saveworld.authentication.web.access.expression;

          import java.util.Collection;

          import org.springframework.expression.EvaluationContext;
          import org.springframework.security.access.AccessDecisionVoter;
          import org.springframework.security.access.ConfigAttribute;
          import org.springframework.security.access.expression.ExpressionUtils;
          import org.springframework.security.core.Authentication;
          import org.springframework.security.web.FilterInvocation;
          import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
          import org.springframework.security.web.access.expression.WebSecurityExpressionHandler;


          public class MyWebExpressionVoter implements AccessDecisionVoter {

          private WebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();

          public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
          assert authentication != null;
          assert object != null;
          assert attributes != null;

          MyWebExpressionConfigAttribute weca = findConfigAttribute(attributes);

          if (weca == null) {
          return ACCESS_ABSTAIN;
          }

          FilterInvocation fi = (FilterInvocation)object;
          EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, fi);

          return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ?
          ACCESS_GRANTED : ACCESS_DENIED;
          }

          private MyWebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
          for (ConfigAttribute attribute : attributes) {
          if (attribute instanceof MyWebExpressionConfigAttribute) {
          return (MyWebExpressionConfigAttribute)attribute;
          }
          }
          return null;
          }

          public boolean supports(ConfigAttribute attribute) {
          return attribute instanceof MyWebExpressionConfigAttribute;
          }

          public boolean supports(Class<?> clazz) {
          return clazz.isAssignableFrom(FilterInvocation.class);
          }

          public void setExpressionHandler(WebSecurityExpressionHandler expressionHandler) {
          this.expressionHandler = expressionHandler;
          }

          }
            回復  更多評論
            

          # re: SpringSecurity使用記錄(六)-- 本地配置二 2012-05-17 11:11 cgh
          @taochen1984
          好像還涉及到MyWebExpressionConfigAttribute,麻煩您發下源碼吧,謝啦。  回復  更多評論
            

          主站蜘蛛池模板: 蒙城县| 塔城市| 古浪县| 阜城县| 贵德县| 寿光市| 都匀市| 车致| 苗栗市| 盖州市| 黑山县| 青浦区| 萝北县| 辉南县| 搜索| 三穗县| 鹿邑县| 靖宇县| 尖扎县| 锦屏县| 余江县| 元江| 怀来县| 永德县| 烟台市| 遵化市| 钟祥市| 手游| 石狮市| 贵阳市| 固镇县| 楚雄市| 本溪| 丰县| 登封市| 湛江市| 西贡区| 四平市| 大宁县| 宣城市| 靖江市|