How to integrate Spring Security and Struts2

12,573

Solution 1

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.

Solution 2

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.

Share:
12,573
user962206
Author by

user962206

Updated on June 29, 2022

Comments

  • user962206
    user962206 almost 2 years

    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.

  • user962206
    user962206 over 11 years
    wouldn't I annotate hasRole inside an action class?
  • Alex
    Alex over 11 years
    If you need to do it in a Java action class you can check it with SecurityContextHolderAwareRequestWrapper.isUserInRole("ROLE_‌​ADMIN")
  • user962206
    user962206 over 11 years
    are there any tutorials regarding annotations? specifically for struts2?
  • Alex
    Alex over 11 years
    there is a plugin named struts2-annotation: struts.apache.org/2.2.1/docs/struts-2-annotations.html and also for spring security like @PreAuthorize etc static.springsource.org/spring-security/site/docs/3.0.x/…
  • user962206
    user962206 over 11 years
    if I download the struts2-annotation will it automatically have that @PreAuthorize?
  • Alex
    Alex over 11 years
    no @PreAuthorize is from spring security. Struts annotations are @Action for example.
  • user962206
    user962206 over 11 years
    do I nee another jar for @PreAuthorize maybe like Spring-struts2 annotation? or something like that?
  • user962206
    user962206 over 11 years
    I'll look into it Spring Security first. then I'll get back here
  • Gnanz
    Gnanz over 9 years
    @theadam spring's doc link broken
  • theadam
    theadam over 9 years
    @granz Thanks for the tip, updated now. They have migrated the documentation. The link works now.