I've done tons of googling regarding this issue and up to now I could not find any tutorial regarding integrating Struts2 and Spring Security.
My question is that How would I integrate Spring Security and Struts2?
Where I want certain actions or pages to be restricted, like the admin page/url should be accessed only by an administrator and other things like that if a user tried to accessed that page he or she would be redirected to another page.
Let's say you need to secure what's accessible on the /admin/*
path. You need to declare the Spring Security Filter in your web.xml
, the Struts filter should come after so that if you are accessing /admin
it will be Spring Security that handle the request first and will be able to let it pass or block it depending on the role of the user:
<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>/admin/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
You then declare your spring security context:
<http>
<intercept-url pattern="/*" filters="none" />
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page="/login" />
<logout logout-url="/logout" />
</http>
I propose that you use the struts2-convention
plugin so that URLs like /login
are bound automatically to a class named let's say com.foo.bar.actions.LoginAction
. Same for LogoutAction
Now what is under /admin/*
should be secured by Spring Security, and the rest should be forwarded directly to the Struts2 filter.
Finally, in your JSP you can check if someone is an Admin with:
<sec:authorize access="hasRole('ROLE_ADMIN')">
<p>you are an admin</p>
</sec:authorize>
The rest can be found in any Spring Security tutorial. What's really important is the order of the filters declaration, spring security must be first.
Edit: searching on google, there is also this link that can be of help for you.
This is actually very simple - Spring Security is web framework agnostic :)
You need to define Spring Security filter chain - this is a Java Filter that should be mapped to all requests. The filter will check if the path requires any privilages and if so checks if user is logged in and has those privilages.
Simple setup example.
web.xml (insert to your existing one, alongside struts config):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF/spring/applicationContext-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
Spring security configuration (in the file mentioned in web.xml in contextConfigLocation parameter):
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/js/**" security="none" />
<http pattern="/css/**" security="none" />
<http pattern="/images/**" security="none" />
<http auto-config="false" use-expressions="true">
<http-basic/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<session-management session-fixation-protection="newSession" />
</http>
</beans:beans>
You may extend this as you wish - Spring's documentation is rather well written
You may go along an even simpler auto-config:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
Above options secure your web-app per request path. You may want to secure the actions as well. Adding the below would get you going:
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled" proxy-target-class = "true" />
Let me know what features you need and I can point you in a direction. Keep in mind that namespace config is not a silver bullet - if you need a very custom solution you might need to configure all the spring beans yourself, but the documentation explains this well.