我是 Spring Security 的新手,我无法让 Spring Method Security 在我的 Web 应用程序中工作,尽管(我相信)我已经设置了web.xml
,applicationContext.xml
并applicationContext-security.xml
启用和使用 Spring 方法安全性。这个 Web 应用程序使用 GWT 和 RESTful 服务,我已经通过用户身份验证成功实现了安全性,即强制用户登录到 Web 应用程序 - 甚至使用带有 Keberos 和 Active Directory 的 SPNEGO 实现了单点登录。但是,当我将<global-method-security>
元素添加到安全上下文并针对所需的 Java 方法指定适当的注释时,似乎什么都没有发生!
我特别想开始@PostFilter
工作(但让任何方法安全工作都会很棒!),但是返回的列表没有被过滤,没有产生相关的错误,Tomcat 日志文件中也没有列出任何异常。
我确信有一些非常基本和基本的东西我已经忽略了,但是我所看到的例子都没有清楚地说明所有的先决条件是让方法安全工作,例如我真的需要使用 AOP 吗?又怎样?所有的例子都只是简单地说将<global-method-security>
元素添加到应用程序上下文(具有适当的属性 ie pre-post-annotations="enabled"
),然后使用相应的注释以及您希望保护的方法......然后 - 就像魔术一样 - 它应该工作!
无论如何,这是我的配置文件:
web.xml
<web-app>
<display-name>Jersey Rest Servlet</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
classpath:applicationContext-security.xml
</param-value>
</context-param>
<!-- Hook into Spring Security framework -->
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>JerseyRESTService</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<load-on-startup>1<load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyRESTService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/jsp/Home.jsp</welcome-file>
</welcome-file-list>
</web-app>
应用程序上下文.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="com.myorg.webservices.impl" />
<bean id="mongo" class="com.mongodb.Mongo">
<constructor-arg name="host" value="localhost" />
<constructor-arg name="port" value="27017" />
</bean>
<bean id="db" class="com.myorg.dao.DBFactory">
<constructor-arg name="mongo" ref="mongo">
<constructor-arg name="name" value="mydatabase" />
</bean>
</beans>
applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<!-- Enable annotations-based security -->
<global-method-security pre-post-annotations="enabled" />
<http use-expresions="true">
<intercept-url> pattern="/**" access="isAuthenticated()" /l>
<form-login />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="testadmin" password="password" authorities="supervisor, user" />
<user name="testuser001" password="password" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
最后,包含我希望过滤的方法的 java 源文件。
DomainPageDecorator.java
package com.myorg.client.domain;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
public class DomainPageDecorator extends PageDecorator<DomainData>
{
public DomainPageDecorator (int numberOfRecordsOnPage)
{
this.setPageSize(numberOfRecordsOnPage);
}
" "
" "
" "
/* Use Spring Method Security to only allow 'ACTIVE' objects through */
@PreAuthorize("hasRole('ROLE_USER')")
@PostFilter("filterObject.getStatus()=='ACTIVE' ")
public List<DomainObject> convertToList()
{
List<DomainObject> dataList = new ArrayList<DomainObject>();
for (int i = 0; i < data.getPage().getLength(); i++)
{
dataList.add(new DomainObject(data.getPage().get(i) ) );
}
return dataList;
}
public DomainObject getFirstItem()
{
return new DomainObject(data.getPage().get(0) );
}
}
谁能告诉我我错过了什么或做错了什么?
注意:我在一个安全的环境中工作,这会阻止我将堆栈跟踪和大型代码段等从我的开发机器发布到互联网上。但是,即使我将全部输入,我仍然应该能够提供帮助解决此问题所需的任何进一步信息:-( 对任何错别字提前道歉