Reputation: 1738
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:
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>
Upvotes: 1
Views: 2438
Reputation: 1678
You are directly accessing some jsp's without using a handler. e.g.
<security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:form-login login-page="/login.jsp" authentication-failure-url="/denied.jsp"
default-target-url="/home.jsp"/>
So security will work until it find your login, denied and home jsp's at root.
Simplest thing you can do is change them to /WEB-INF/views url. But I think it it not the practice to access jsp's directly. You should use a handler method. I'll give a example below.
@RequestMapping(value="login", method= RequestMethod.GET)
public String showLogin(){
return "login";
}
Then apply security for Request mapping url.
<security:intercept-url pattern="login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
Now your security logic is not in bind with your files physical location. It's always good to keep things loosely coupled.
Use spring security documentation for more details.
Upvotes: 0
Reputation: 15109
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.
Upvotes: 1