Spring 3 MVC + Security

Issue

I’ve got two sample projects – 1st is Spring 3 MVC project and 2nd is Spring 3 Security project…both are working well…But when I try to create application, where I implement both security and MVC, I can’t realize how to make it work. My app structure looks like this:
enter image description here

When I have jsp pages in / then security works…But when I want to put them to /WEB-INF/views to be able to map the @Controller for them, then it doesn’t work…Can somebody please advice me, where and what to change, to make it work with JSP in /WEB-INF/views/?

My config files:

/WEB-INF/spring/appServlet/servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

<context:component-scan base-package="cz.cvut.fit" />

    <context:component-scan base-package="com.chickstarter.web" />
<resources location="/resources/**" mapping="/src/webapp/resources"/>


     </beans:beans>

/WEB-INF/spring/appServlet/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
 xmlns="http://java.sun.com/xml/ns/javaee"   
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/spring/root-context.xml</param-value>
 </context-param>
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
 <url-pattern>/</url-pattern>
 </servlet-mapping>
<!-- START: Spring Security -->
<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>
<!-- END: Spring Security -->
 <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext-web.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
 <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/data/*</url-pattern>
</servlet-mapping>
</web-app>

/src/main/resources/applicationContext-sexurity.xml

<beans xmlns:security="http://www.springframework.org/schema/security"
   xmlns="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.0.xsd
             http://www.springframework.org/schema/security
             http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<security:http pattern="/login.jsp*" security="none"/>
<security:http pattern="/denied.jsp" security="none"/>

<security:http auto-config="true" access-denied-page="/denied.jsp" servlet-api-provision="false">
    <security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <security:intercept-url pattern="/edit/**" access="ROLE_EDIT"/>
    <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
    <security:intercept-url pattern="/**" access="ROLE_USER"/>
    <security:form-login login-page="/login.jsp" authentication-failure-url="/denied.jsp"
                         default-target-url="/home.jsp"/>
    <security:logout/>
</security:http>

<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="adam" password="adampassword" authorities="ROLE_USER"/>
            <security:user name="jane" password="janepassword" authorities="ROLE_USER, ROLE_ADMIN"/>
            <security:user name="sue" password="suepassword" authorities="ROLE_USER, ROLE_EDIT"/>
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

 </beans>

Solution

First, you have 2 dispatcher servlets defined in your web.xml, one loads applicationContext and the other servlet-context. Is that actually necessary? You could use the import tag in servlet-context if you really want to split apart files.

Second, you also have 2 <resources> tags. First one is sufficient since the path scanning starts from the webapp folder.

Third, make all your jsp’s accessible from only their controllers. Exclude urls which you want to access without authentication:

<security:intercept-url pattern="login/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

Above will exclude all resouces accessible by RequestMapping of the below controller:

LoginController :

@Controller
@RequestMapping("login")
public class LoginController 
{

    @RequestMapping(method = RequestMethod.GET)
    public String login(Authentication authentication)
    {
        if ((authentication != null) && authentication.isAuthenticated())
        {
            return "redirect:dashboard";
        }
        return "login";
    }

    @RequestMapping(value="doSomething", method = RequestMethod.POST)
    public String postLogin(Authentication authentication)
    {
        // Something else
    }

}

The returned “login” will open the page defined by your InternalResourceViewResolver and will look for the page under WEB-INF/views.

In your security files change all paths from jsp pahts to RequestMapping paths.

Answered By – Varun Achar

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published