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:
src="https://i.stack.imgur.com/lMkOa.png" alt="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
Answer Checked By - Candace Johnson (JavaFixing Volunteer)