I am trying access URLs (e.g. /user/subscriptions) secured with Spring(v.4.1.0) Security(v.3.2.5) and I am getting the following error , after submitting username/password and csrf token:
HTTP ERROR 405 Problem accessing /j_spring_security_check. Reason: Request method 'POST' not supported
I have the following configurations. web.xml
<!--Hook into 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>/rest_services/*</url-pattern>
<url-pattern>/users/*</url-pattern>
</filter-mapping>
Spring security context:
<security:http auto-config="false" authentication-manager-ref="jdbcAuthenticationManager">
<security:intercept-url pattern="/users/**/*" access="ROLE_USER"/>
<security:intercept-url pattern="/login/custom_login" access="ROLE_ANONYMOUS"/>
<security:form-login
login-page="/login/custom_login"
username-parameter="username"
password-parameter="password" />
<security:logout logout-success-url="/custom_login?logout" />
<!-- enable csrf protection -->
<csrf/>
</security:http>
CustomLoginController:
@Controller
@RequestMapping("/login")
public class CustomLoginController {
protected static Logger LOG = Logger.getLogger(CustomLoginController.class);
//Spring Security see this :
@RequestMapping(value = "custom_login", method = RequestMethod.GET)
public String login(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
return "login_def";
}
}
Tiles definition
<definition name="login_def" extends="defaultTemplate_m">
<put-attribute name="title" value="Podcastpedia"/>
<put-attribute name="page_description" value="Podcastpedia.org, knowledge to go"/>
<put-attribute name="body-id" value="latest-episodes-podcast-subscriptions" />
<put-attribute name="content" value="/WEB-INF/jsp/user/login.jsp"/>
</definition>
login.jsp
<form name='loginForm'
action="<c:url value='/j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan='2'>
<input name="submit" type="submit" value="submit" />
</td>
</tr>
</table>
<input type="hidden"
name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
Tiles-context configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Views mapped in views.properties (PDF, XLS classes, and others) -->
<bean id="contentNegotiatingResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order"
value="#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE}" />
<property name="favorPathExtension" value="true"/>
<property name="contentNegotiationManager">
<bean class="org.springframework.web.accept.ContentNegotiationManager">
<constructor-arg>
<bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
<constructor-arg>
<map>
<entry key="html" value="text/html"/>
<entry key="pdf" value="application/pdf"/>
<entry key="xsl" value="application/vnd.ms-excel"/>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
<entry key="atom" value="application/xml"/>
</map>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
<property name="order" value="#{contentNegotiatingResolver.order+1}" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="order" value="#{tilesViewResolver.order+1}" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tile-defs/templates.xml</value>
<value>/WEB-INF/tile-defs/definitions.xml</value>
</list>
</property>
</bean>
</beans>
Same configuration in project without Tiles works without any problem. Can you advise me on what I could be doing wrong... The attempt is available at https://github.com/podcastpedia/podcastpedia-web/tree/spring-security-custom-login
Question is pretty much similar to the one here HTTP Status 405 - Request method 'POST' not supported occurs when try to submit spring security's custom login form, but there are no answers yet...
What helped was setting the login-processing-url to /j_spring_security_check" in the form-login configuration:
<form-login
login-page="/login/custom_login"
login-processing-url="/j_spring_security_check"
username-parameter="username"
password-parameter="password" />