Reputation: 3
I'm new to Spring Security and I'm having trouble getting Spring Method Security to work in my web application although (I believe) I've setup the web.xml
, applicationContext.xml
and applicationContext-security.xml
to enable and use Spring method security. This web application uses GWT and RESTful services and I have successfully implemented security via user authentcation i.e. forcing users to login to the web app - and even implemented Single-Sign-On using SPNEGO with Keberos and Active Directory. However, when I add the <global-method-security>
element to the security context and specify appropriate annotations against the desired Java methods, nothing appears to happen!
I'm specifically trying to get @PostFilter
to work (but getting any method security to work would be great!), however the returned list is NOT filtered, no related errors are generated and no exceptions are listed in the Tomcat log files.
I'm sure there's something quite basic and fundamental that I've overlooked but none of the examples I've seen clearly state what ALL of the pre-requistes are to get method security to work e.g. do I really need to use AOP and if so, how? All the examples simply say to add the <global-method-security>
element to the application context (with appropriate attributes i.e. pre-post-annotations="enabled"
) and then use the corresponding annotations along-side the methods you wish to secure.....then - like magic - it should work!
Anyway, here's my configuration files:
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>
applicationContext.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>
And finally, the java source file containing the method I wish to filter on.
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) );
}
}
Can anyone please tell me what am I missing or doing wrong?
NB: I work in a secured environment which prevents me from posting stack traces and large code segments etc onto the internet from my development machine. However, I should still be able provide any further information that's needed to help resolve this problem even though I'll be typing it all up :-( Apologies in advance for any typos
Upvotes: 0
Views: 802
Reputation: 7817
You can apply these annotations only to beans declared in some spring context file. From provided code it looks like your DomainPageDecorator class is not managed by spring. Make it managed:
new
keyword). Use @Inject
or XML.Upvotes: 1