2013-09-06 3 views
1

Я новичок в Spring Spring & Spring Security Frameworks и пытается защитить приложение REST Java EE 7, работающее на последней стабильной сборке Glassfish с использованием Spring Security v3.1.4.Spring Security - «global-method-security» не работает

Все в порядке, но Мне не удается сделать работу «global-method-security»! Вот мои конфиги, любая помощь будет очень признательна.

web.xml: контекст приложения

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/spring/*.xml 
    </param-value> 
</context-param> 

<filter> 
    <filter-name>filterChainProxy</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>filterChainProxy</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>  

Spring сконфигурирован для предварительной аутентификации и выглядит следующим образом:

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"> 
     <property name="alwaysUseJndiLookup" value="true" /> 
    </bean> 

    <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> 
     <sec:filter-chain-map request-matcher="ant"> 
      <sec:filter-chain pattern="/api/authentication" filters="none"/> 
      <sec:filter-chain pattern="/**" filters="sif,requestHeaderAuthFilder,logoutFilter,etf,fsi"/> 
     </sec:filter-chain-map> 
    </bean> 

    <bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> 

    <sec:authentication-manager alias="authenticationManager"> 
     <sec:authentication-provider ref='preAuthenticatedAuthenticationProvider'/> 
    </sec:authentication-manager> 

    <bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
     <property name="preAuthenticatedUserDetailsService"> 
      <bean id="userDetailsServiceWrapper" 
        class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> 
       <property name="userDetailsService" ref="preAuthenticatedUserDetailsService"/> 
      </bean>   
     </property> 
    </bean> 

    <bean id="preAuthenticatedUserDetailsService" 
      class="org.someUserDetailsService"/> 

    <bean id="requestHeaderAuthFilder" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter"> 
     <property name="authenticationManager" ref="authenticationManager"/> 
     <property name="principalRequestHeader" value="sometoken"/>  
    </bean> 

    <bean id="preAuthenticatedProcessingFilterEntryPoint" 
      class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/> 

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
     <constructor-arg value="/"/> 
     <constructor-arg> 
      <list> 
       <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 
      </list> 
     </constructor-arg> 
    </bean> 

    <bean id="servletContext" class="org.springframework.web.context.support.ServletContextFactoryBean"/> 

    <bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter"> 
     <property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/> 
    </bean> 

    <bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> 
     <property name="allowIfAllAbstainDecisions" value="false"/> 
     <property name="decisionVoters"> 
      <list> 
       <ref bean="roleVoter"/> 
       <ref bean="authenticatedVoter"/> 
      </list> 
     </property> 
    </bean> 

    <bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> 
     <property name="authenticationManager" ref="authenticationManager"/> 
     <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>  
     <property name="securityMetadataSource"> 
      <sec:filter-security-metadata-source use-expressions="true"> 
       <!--<sec:intercept-url pattern="/api/authentication" access="permitAll"/>--> 
       <sec:intercept-url pattern="/**" access="isAuthenticated()"/> 
      </sec:filter-security-metadata-source> 
     </property> 

    </bean> 

    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/> 
    <bean id="authenticatedVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"/> 

    <bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/> 

И следующая весна ACL Configuration:

<sec:global-method-security    
     pre-post-annotations="enabled"> 
     <sec:expression-handler ref="expressionHandler" /> 
    </sec:global-method-security> 


    <bean id="expressionHandler"    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
     <property name="permissionEvaluator" ref="aclPermissionEvaluator" /> 
    </bean> 

    <bean name="aclPermissionEvaluator" 
      class="org.CustomPermissionEvaluator"> 
     <constructor-arg name="aclService" ref="aclService" /> 
     <property name="sidRetrievalStrategy" ref="someSidRetrievalStrategy" /> 
    </bean> 

    <bean id="lookupStrategy" 
      class="org.springframework.security.acls.jdbc.BasicLookupStrategy"> 
     <constructor-arg name="dataSource" ref="dataSource" /> 
     <constructor-arg name="aclCache" ref="aclCache" /> 
     <constructor-arg name="aclAuthorizationStrategy" ref="aclAuthorizationStrategy" /> 
     <constructor-arg name="auditLogger" ref="auditLogger" /> 
    </bean> 

    <bean id="aclCache" 
      class="org.springframework.security.acls.domain.EhCacheBasedAclCache"> 
     <constructor-arg> 
      <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"> 
       <property name="cacheManager"> 
        <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> 
       </property> 
       <property name="cacheName" value="aclCache" /> 
      </bean> 
     </constructor-arg> 
    </bean> 

    <bean id="aclAuthorizationStrategy" 
      class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> 
     <constructor-arg name="auths"> 
      <list> 
       <!-- authority for taking ownership --> 
       <bean 
        class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
       <!-- authority to modify auditing --> 
       <bean 
        class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
       <!-- authority to make general changes --> 
       <bean 
        class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
        <constructor-arg value="ROLE_ADMIN" /> 
       </bean> 
      </list> 
     </constructor-arg> 
     <property name="sidRetrievalStrategy" ref="someSidRetrievalStrategy"/> 
    </bean> 

    <bean id="someSidRetrievalStrategy" class="org.SomeSidRetrievalStrategyImpl"/> 

    <bean id="auditLogger" 
      class="org.springframework.security.acls.domain.ConsoleAuditLogger" /> 


    <jee:jndi-lookup 
     id="dataSource" 
     jndi-name="springacl" /> 


    <bean id="aclService" name="aclService" 
      class="org.springframework.security.acls.jdbc.JdbcMutableAclService"> 
     <constructor-arg name="dataSource" ref="dataSource" /> 
     <constructor-arg name="lookupStrategy" ref="lookupStrategy" /> 
     <constructor-arg name="aclCache" ref="aclCache" /> 
     <property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))" /> 
     <property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))" /> 
    </bean> 

И метод, который я хочу применить проверку разрешений, выглядит так:

@GET 
    @Path("/{id}") 
    @Produces(MediaType.APPLICATION_JSON) 
    @PreAuthorize("hasPermission(#id, 'read')") 
    public Project getProject(@PathParam("id") Long id) { 
    } 


Где я делаю что-то неправильно?

ответ

6

Я решил проблему, поэтому хочу поделиться информацией здесь, чтобы помочь другим найти причины, по которым функция глобальной безопасности SS может не работать.

Благодаря Arten Bilan для указания меня в правильном направлении. Прямым ответом на мой вопрос может быть: , если вы хотите защитить свой код, который не определен как «Весенние бобы», вы должны использовать «AspectJ auto-proxying» (режим = «aspectj»). Однако вам может потребоваться больше, чтобы заставить его работать, как и я.

Дело в том, чтобы включить AspectJ, вы должны ткут свой код с AnnotationSecurityAspect из пружинных безопасности-аспектов модуль, как описано here. Особенно сообщение Luke Taylor было полезно для меня.

Чтобы это произошло, вы должны скомпилировать свой код с помощью компилятора aspectj.Если вы используете Maven, как мне теперь делать, следующие конфигурации могут быть полезны (как обсуждалось here):

Первый набор с использованием режима AspectJ:

<sec:global-method-security    
     pre-post-annotations="enabled" 
     mode="aspectj" 
     proxy-target-class="true"> 
     <sec:expression-handler ref="expressionHandler" /> 
    </sec:global-method-security> 

Добавить зависимость для модуля пружинные-безопасности-аспекты:

 <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-aspects</artifactId> 
      <version>3.1.4.RELEASE</version> 
     </dependency> 

и, наконец, добавить следующий Maven плагин и конфигурации для времени компиляции ткачество:

 <plugin> 
       <groupId>org.codehaus.mojo</groupId> 
       <artifactId>aspectj-maven-plugin</artifactId> 
       <version>1.4</version> 
       <configuration> 
        <showWeaveInfo>true</showWeaveInfo> 
        <source>1.7</source> 
        <target>1.7</target> 
        <Xlint>ignore</Xlint> 
        <complianceLevel>1.7</complianceLevel> 
        <encoding>UTF-8</encoding> 
        <verbose>false</verbose> 
        <aspectLibraries> 
         <aspectLibrary> 
          <groupId>org.springframework.security</groupId> 
          <artifactId>spring-security-aspects</artifactId> 
         </aspectLibrary> 
        </aspectLibraries> 
       </configuration> 
       <executions> 
        <execution> 
         <goals> 
          <goal>compile</goal> 
          <goal>test-compile</goal> 
         </goals> 
        </execution> 
       </executions> 
       <dependencies> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjrt</artifactId> 
         <version>${aspectj.version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjtools</artifactId> 
         <version>${aspectj.version}</version> 
        </dependency> 
       </dependencies> 
      </plugin> 

Это сделало работу для меня.

2

Похоже, вы должны следовать с Рекомендацией для от Spring Security Reference Manual:

Аннотированных методы будут обеспечены только для случаев, которые определяются как Spring фасоль (в том же контексте приложения, в котором метод-безопасность включен).

Аналогичная проблема обсуждается здесь: How can <global-method-security> work on my controller by Spring-Security? Посмотреть последнее сообщение.

+0

Давать только ссылку, так как ответ не является хорошим способом. Если ссылка обновлена ​​или удалена в будущем, вы ответите автоматически. Было бы лучше, если бы вы дали некоторое объяснение, а затем дали ссылку в качестве ссылки. – Sankumarsingh

+0

Благодарим вас за ответ Артем. Если экземпляр должен быть компонентом Spring, чтобы иметь возможность использовать аннотации для защиты метода, значит ли это, что я не могу использовать его в веб-приложении J2EE? Или это было бы возможно с помощью «AspectJ auto-proxying» (mode = «aspectj»)? Как? – archangle

+0

Ну. Опять же из документации SS: B.3.1 Этот элемент является основным средством добавления поддержки для защиты методов в Spring Security beans. Методы могут быть защищены с помощью аннотаций (определенных на уровне интерфейса или класса) или путем определения набора pointcut в качестве дочерних элементов с использованием синтаксиса AspectJ. –

Смежные вопросы