Search code examples
javaspring-bootspring-securityopenapispringdoc

Documenting Spring Security's form login endpoint with springdoc-openapi


I need help finding a way to make Spring Security's form login endpoint work in swagger-ui with springdoc-openapi. I'm using SpringBoot 2.7.5 and Spring Security 5.7.4, and these are the rest of the project's dependencies:

  <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.6.12</version>
    </dependency>
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-security</artifactId>
        <version>1.6.12</version>
    </dependency>
</dependencies>

Spring Security simple configuration for securing /foos/ endpoints with form login and defining user login details.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
            .antMatchers("/foos/**")
            .authenticated()
            .and()
            .formLogin()
            .permitAll()
            .and()
            .logout()
            .permitAll();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder passwordEncoder) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("user")
            .password(passwordEncoder.encode("password"))
            .roles("USER");
}
}

And the foos Controller:

@RestController
@RequestMapping("foos")
public class FooController {

@GetMapping(value = "/{id}")
public Foo findById(@PathVariable("id") final Long id) {
    return new Foo(randomAlphabetic(6));
}

@GetMapping
public List<Foo> findAll() {
    return Lists.newArrayList(new Foo(randomAlphabetic(6)));
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Foo create(@RequestBody final Foo foo) {
    return foo;
}
}

Also supplying this property: springdoc.show-login-endpoint=true and the login endpoint is exposed in swagger-ui but the only problem is that the only request body type is application/json and this sends the credentials as json in the request body which results in null username/password in UsernamePasswordAuthenticationFilter.

Sample code repo: https://github.com/adrianbob/springdoc-form-login

Can the request body type be configured to application/x-www-form-urlencoded, so that form login works?


Solution

  • I've raised an issue which was categorised as a bug and fixed. The latest release does not have this problem anymore, version 1.6.13.