5
votes

I've generated a Spring Boot web application using Spring Initializer, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.

Technologies used:

Spring Boot 1.4.2.RELEASE, Spring 4.3.4.RELEASE, Thymeleaf 2.1.5.RELEASE, Tomcat Embed 8.5.6, Maven 3, Java 8

This is my security config class:

@Configuration
@EnableWebSecurity
@PropertySource("classpath:/com/tdk/iot/config/app-${APP-KEY}.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${securityConfig.formLogin.loginPage}")
    private String loginPage;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .formLogin()
                .loginPage(loginPage)
                .permitAll()
                .loginProcessingUrl("/login")
                .failureUrl("/login.html?error=true")
                .defaultSuccessUrl("/books/list")
                .and()
            .exceptionHandling()
                .accessDeniedPage("/denied")
                .and()
            .authorizeRequests()
                .antMatchers("/mockup/**").permitAll()
                .antMatchers("/books/**").permitAll()
                .antMatchers("/welcome/**").authenticated()
                .and()
            .logout()
                .permitAll()
                .logoutSuccessUrl("/index.html");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .passwordEncoder(new StandardPasswordEncoder())
                .withUser("test1").password("test1").roles("ADMIN").and()
                .withUser("test2").password("test2").roles("USER").and()
                .withUser("test3").password("test3").roles("SUPERADMIN");
    }

    @Bean
    public  static PropertySourcesPlaceholderConfigurer propertyDefaultConfig() {
        return new PropertySourcesPlaceholderConfigurer();
    }   
}

Here the LoginController

 @Controller
 public class LoginController {

     @RequestMapping(value={ "/", "/tdk/login"}, method = { RequestMethod.POST,RequestMethod.GET})
     public String welcome(Map<String, Object> model) {
         return "tdk/login";
     }
 }

and the template:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>

<div class="wrap">
    <div class="login">
        <div class="logo"></div>

            <form th:action="@{/login.html}" method="post">

                <p th:if="${loginError}" class="error">Wrong user or password</p>

                <div class="input_label"><i class="fa fa-user"></i><input type="text" name="user" placeholder="User" /></div>
                <div class="input_label"><i class="fa fa-key"></i><input type="password" name="pass" placeholder="Password" /></div>
                <input type="submit" value="LOGIN" />
             </form>
        <div class="forget">
           <!--  <a href="#">Do you forgot your password?</a><br/> -->
            <br/>            
        </div>          
    </div>
</div>

</body>
</html>

but when I access with test1 / test1 I got this error:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sun Mar 05 20:16:11 CET 2017 There was an unexpected error (type=Method Not Allowed, status=405). Request method 'POST' not supported

3
BTW: You have some more errors in your code. The default parameter names are username and password, but you use user and pass in your login page. You have to change the configuration or the login page. - dur

3 Answers

1
votes

Your login page calls /login.html with HTTP POST, but your server doesn't provide such a request mapping.

The configured URL in your Spring Security configuration:

.loginProcessingUrl("/login")

is not matching the URL in your login page:

<form th:action="@{/login.html}" method="post">

See also AbstractAuthenticationFilterConfigurer#loginProcessingUrl:

Specifies the URL to validate the credentials.

0
votes

try this code

.failureUrl("/tdk/login?error=true")

Controller

@Controller
 public class LoginController {

     @RequestMapping(value={ "/", "/tdk/login"},params = {"error"},method=RequestMethod.POST)
     public String welcome(@RequestParam(value = "error", required = false) int error , ModelMap model) {
if (error == 1) {
            model.addAttribute("msg", "Invalid Username or Password");
            return "tdk/login";
        }
else{
                return "redirect:home";

}

     }
 }
-2
votes

Default method controller for @RequestMapping is GET, not POST.

You need to specify the method on the @requestMapping.

@RequestMapping(value={ "/", "/tdk/login"}, method = RequestMethod.POST)