1

I prepared and extended this existing spring example which is running fine. You can simply login with "user" and "password" and afterwards you get forwarded to user/index.

Using this controller

@Controller
public class LoginController {
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/login-error")
    public String loginError(Model model) {
        model.addAttribute("loginError", true);
        return "login";
    }
}

But as soon i run the example test which is using WebClient the same login is causing the exception:

com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 405 Request method 'POST' not supported for http://localhost:8080/login

which is strange because the application itself works just fine.

EDIT: This is the test method causing the problem

@And("^the user clicks the login button$")
public void theUserClicksTheLoginButton() throws IOException {
    page = page.getElementById("login").click();
}

I didn't expect that the click method of WebClient is using POST instead of realy executing the input field in the html.

<form th:action="@{/login}" method="post">
    <label for="username">Username</label>:
    <input type="text" id="username" name="username" autofocus="autofocus" /> <br />
    <label for="password">Password</label>:
    <input type="password" id="password" name="password" /> <br />
    <input type="submit" id="login" value="Log in" />
</form>

EDIT 2: Ok maybee i schould claryfy my question a bit. I know a login should done over POST, and my @Controller is only providing @GetMapping but this is ok because spring security is handling the POST requests as i can see in the header while login in:

enter image description here

My question is why is it working fine while running the app, and why hasn't it the same behavior when using WebClient.

Ben1980
  • 186
  • 1
  • 3
  • 15
  • Are you using Spring Security? – The Head Rush Jun 05 '18 at 13:46
  • Yes i do -> see dependencies on build.gradle and `org.springframework.security.samples.config.SecurityConfig` – Ben1980 Jun 05 '18 at 13:49
  • Spring Security provides a login controller that can be setup by overriding the `configure(HttpSecurity http)` method. – The Head Rush Jun 05 '18 at 13:52
  • And this should be done for testing purposes to have the app behaveing the same way as running the app regular? – Ben1980 Jun 05 '18 at 13:55
  • This is don e anyway in SecurityConfig.java [link](https://github.com/Ben1980/spring-sec-problem/blob/master/src/main/java/org/springframework/security/samples/config/SecurityConfig.java) – Ben1980 Jun 05 '18 at 13:58

2 Answers2

2

I'm not very familiar with setting up Spring with Cucumber, and I'm not sure about mixing both SpringRunner and Cucumber runners in the same setup.

I've updated your test setup like this:

@RunWith(SpringRunner.class)
@WebMvcTest
@ContextConfiguration
@Import(SecurityConfig.class)
public class LoginFeatureStepDefinition {
    private String username;
    private String password;
    private HtmlPage page;

    @Autowired
    private WebClient webDriver;
  1. I've replaced @SpringBootTest with @WebMvcTest, as the mockmvc auto-configuration will take care of the webclient setup for you. If you wanted to start an actual server with the whole application and test it with an HTTP client, you need to setup @SpringBootTest in a different way.
  2. In a MockMvc setup, the security configuration is not imported by default, so you need to import it
Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
-1

The web client is calling the service via POST request which is causing the exception : Request method 'POST' not supported.The service side looks good.

Arun
  • 3,701
  • 5
  • 32
  • 43
  • Yes that i realized from the exception also. The question is how to execute the login so its working as it does wenn a real user is clicking on login. – Ben1980 Jun 01 '18 at 05:33
  • Try changing the mapping to `@Postmapping` – Arun Jun 01 '18 at 11:32
  • Thats not really what i am looking for. I try to understand why a `@Postmapping` is not necessary if a real user is clicking on it, while the WebClient needs one. This behaviour doesn't make sense to me, i expect the same behaviour. – Ben1980 Jun 01 '18 at 11:55
  • `
    ` -> It will never reach a get mapping as the UI method is `POST`. The exception you are getting is correct and expected. `GET` should be used for retrieving data. We can send parameters only via URL or request headers. `POST` is used to send the data to server. Submitting forms should be done in POST only. the username and password should not be sent via `URL` params but via request body.
    – Arun Jun 01 '18 at 13:13
  • Yes i totally agree with you, but that's not my question. I edited my post to make my issue hopefully a bit clearer. – Ben1980 Jun 01 '18 at 20:00