Search code examples
xmlspringspring-mvcjakarta-eespring-security

Login with Spring Security : Request method 'POST' not supported


I have trouble logging in with Spring Security. the login page displays fine but whenever i want to actually log in i get the following error :

Etat HTTP 405 - Request method 'POST' not supported.

Since i'm using Spring Security 4.0.1 note that the /login used in the form action references the built in authentication engine of spring security. therefore it is not the same as the /login in the login method in the controller.

Here are the relevant files :

login.jsp :

<body onload='document.loginForm.username.focus();'>

<h1>Spring Security Custom Login Form (Annotation)</h1>

<div id="login-box">

    <h2>Login with Username and Password</h2>

    <c:if test="${not empty error}">
        <div class="error">${error}</div>
    </c:if>
    <c:if test="${not empty msg}">
        <div class="msg">${msg}</div>
    </c:if>

    <form name='loginForm'
        action="<c:url value='/login' />" 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>
</div>

MainController :

    @Controller
    public class MainController {
    
    private static final Logger logger = LoggerFactory.getLogger(MainController.class);
    
    @RequestMapping(value = "/login", method=RequestMethod.GET)
    public ModelAndView login(
            @RequestParam(value="erreur",required = false) String erreur,
            @RequestParam(value="logout",required = false) String logout) {
        ModelAndView model = new ModelAndView();
        if(erreur != null) {
            model.addObject("erreur", "Identifiants incorrectes");
        }
        if(logout != null) {
            model.addObject("msg","you have been logged out successfully");
        }
        return model;
    }
    
    @RequestMapping(value = "/admin**", method = RequestMethod.GET)
    public String admin(Locale locale, Model model) {
        logger.info("Bienvenue ! vous êtes en {}.", locale);
        
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        
        String formattedDate = dateFormat.format(date);
        
        model.addAttribute("serverTime", formattedDate );
        
        return "admin";
    }
    
    @RequestMapping(value = "/403", method = RequestMethod.GET)
    public ModelAndView accesssDenied() {
 
      ModelAndView model = new ModelAndView();
 
      //verifier si l'utilisateur est connecté
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      logger.info("Authentification:"+auth);
      if (!(auth instanceof AnonymousAuthenticationToken)) {
        UserDetails userDetail = (UserDetails) auth.getPrincipal(); 
        model.addObject("username", userDetail.getUsername());
      }
 
      model.setViewName("403");
      return model;
 
    }
    
    @RequestMapping(value = {"/","/index"}, method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Bienvenue ! vous êtes en {}.", locale);
        
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        
        String formattedDate = dateFormat.format(date);
        
        model.addAttribute("serverTime", formattedDate );
        
        return "index";
    }

spring-security.xml:

<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.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">
 
    <http auto-config="true" use-expressions="true">
        <access-denied-handler error-page="/403" />
        <intercept-url pattern="/admin**" access="hasRole('admin')" />
        <form-login 
            login-page="/login" 
            default-target-url="/index" 
            authentication-failure-url="/login?error" 
            username-parameter="username"
            password-parameter="password" />
        <logout logout-success-url="/login?logout" invalidate-session="true"/>
        <!--   enable csrf protection -->
        <csrf/> 
    </http>
    
 
    <authentication-manager>
      <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"
          users-by-username-query=
            "select login,pwd, enabled from utilisateur where login=?"
          authorities-by-username-query=
            "select login, role from role where login =?" />
      </authentication-provider>
    </authentication-manager>
</beans:beans>

Solution

  • I just found what was wrong,in the login JSP i'm using expression language to evaluate the csrf parameter name and token and i had simply forgot to add the <%@ page isELIgnored="false"%> propriety in the login page.