BAEL-5325: Add Spring Security login/logout API with Springdoc (#13027)
* BAEL-5325: Add Spring Security login/logout API with Springdoc * Updated Spring version and using annotations for Basic Auth config * Added tests * Removed unused dependencies * Removed dependencies which were accidentally added. * Removed plugins which were accidentally added. * Removed property which was accidentally added.
This commit is contained in:
parent
10d561451a
commit
f45b2c8659
|
@ -43,6 +43,7 @@
|
||||||
<module>spring-security-web-rest-basic-auth</module>
|
<module>spring-security-web-rest-basic-auth</module>
|
||||||
<module>spring-security-web-rest-custom</module>
|
<module>spring-security-web-rest-custom</module>
|
||||||
<module>spring-security-web-rest</module>
|
<module>spring-security-web-rest</module>
|
||||||
|
<module>spring-security-web-springdoc</module>
|
||||||
<module>spring-security-web-sockets</module>
|
<module>spring-security-web-sockets</module>
|
||||||
<module>spring-security-web-thymeleaf</module>
|
<module>spring-security-web-thymeleaf</module>
|
||||||
<module>spring-security-web-x509</module>
|
<module>spring-security-web-x509</module>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
## Spring Security Web Springdoc
|
||||||
|
|
||||||
|
This module contains articles about Springdoc with Spring Security
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Documenting a Spring REST API Using OpenAPI 3.0](https://www.baeldung.com/spring-rest-openapi-documentation)
|
||||||
|
- [Configure JWT Authentication for OpenAPI](https://www.baeldung.com/openapi-jwt-authentication)
|
||||||
|
|
||||||
|
### Running This Project:
|
||||||
|
|
||||||
|
To run the projects use the commands:
|
||||||
|
- `mvn spring-boot:run -Dstart-class=com.baeldung.basicauth.SpringBootSpringdocBasicAuth`
|
||||||
|
- `mvn spring-boot:run -Dstart-class=com.baeldung.formlogin.SpringBootSpringdocFormLogin`
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>spring-security-web-springdoc</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
<name>spring-security-web-springdoc</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Spring Security with Springdoc tutorial</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<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>${springdoc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-security</artifactId>
|
||||||
|
<version>${springdoc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<springdoc.version>1.6.13</springdoc.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.basicauth;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Foo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5422285893276747592L;
|
||||||
|
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Foo(final String name) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
final Foo other = (Foo) obj;
|
||||||
|
if (name == null) {
|
||||||
|
return other.name == null;
|
||||||
|
} else return name.equals(other.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Foo [name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.basicauth;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||||
|
import io.swagger.v3.oas.annotations.info.Info;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@OpenAPIDefinition(info = @Info(title = "Foos API", version = "v1"))
|
||||||
|
@SecurityRequirement(name = "basicAuth")
|
||||||
|
@RequestMapping(value = "foos", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public class FooController {
|
||||||
|
|
||||||
|
private static final int STRING_LENGTH = 6;
|
||||||
|
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public Foo findById(@PathVariable("id") final Long id) {
|
||||||
|
return new Foo(randomAlphabetic(STRING_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<Foo> findAll() {
|
||||||
|
return Lists.newArrayList(new Foo(randomAlphabetic(STRING_LENGTH)), new Foo(randomAlphabetic(STRING_LENGTH)), new Foo(randomAlphabetic(STRING_LENGTH)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
public Foo create(@RequestBody final Foo foo) {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.basicauth;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SpringBootSpringdocBasicAuth {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringBootSpringdocBasicAuth.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.basicauth.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class PasswordEncoderConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.basicauth.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf().disable()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/v3/api-docs/**",
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/swagger-ui.html").permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.httpBasic();
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder passwordEncoder) throws Exception {
|
||||||
|
auth.inMemoryAuthentication()
|
||||||
|
.withUser("user")
|
||||||
|
.password(passwordEncoder.encode("password"))
|
||||||
|
.roles("USER");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.basicauth.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@SecurityScheme(
|
||||||
|
type = SecuritySchemeType.HTTP,
|
||||||
|
name = "basicAuth",
|
||||||
|
scheme = "basic")
|
||||||
|
public class SpringdocConfig {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.formlogin;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SpringBootSpringdocFormLogin {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringBootSpringdocFormLogin.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.formlogin.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class PasswordEncoderConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.formlogin.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf().disable()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/v3/api-docs/**",
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/swagger-ui.html").permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.formLogin()
|
||||||
|
.defaultSuccessUrl("/foos");
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder passwordEncoder) throws Exception {
|
||||||
|
auth.inMemoryAuthentication()
|
||||||
|
.withUser("user")
|
||||||
|
.password(passwordEncoder.encode("password"))
|
||||||
|
.roles("USER");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.formlogin.controller;
|
||||||
|
|
||||||
|
import com.baeldung.formlogin.model.Foo;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||||
|
import io.swagger.v3.oas.annotations.info.Info;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(value = "foos", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@OpenAPIDefinition(info = @Info(title = "Foos API", version = "v1"))
|
||||||
|
public class FooController {
|
||||||
|
|
||||||
|
private static final int STRING_LENGTH = 6;
|
||||||
|
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public Foo findById(@PathVariable("id") final Long id) {
|
||||||
|
return new Foo(randomAlphabetic(STRING_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<Foo> findAll() {
|
||||||
|
return Lists.newArrayList(new Foo(randomAlphabetic(STRING_LENGTH)), new Foo(randomAlphabetic(STRING_LENGTH)), new Foo(randomAlphabetic(STRING_LENGTH)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
public Foo create(@RequestBody final Foo foo) {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.formlogin.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.info.Info;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@OpenAPIDefinition(info = @Info(title = "logout-endpoint"))
|
||||||
|
public class LogoutController {
|
||||||
|
|
||||||
|
@PostMapping("logout")
|
||||||
|
@Operation(description = "End authenticated user session")
|
||||||
|
public void logout() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.baeldung.formlogin.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Foo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5422285893276747592L;
|
||||||
|
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Foo(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
final Foo other = (Foo) obj;
|
||||||
|
if (name == null) {
|
||||||
|
return other.name == null;
|
||||||
|
} else return name.equals(other.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Foo [name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
springdoc.show-login-endpoint=true
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.basicauth;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
class OpenAPIIntegrationTest {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeSwagger_thenRenderIndexPage() {
|
||||||
|
String response = this.restTemplate.getForObject("http://localhost:" + port + "/swagger-ui/index.html", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertTrue(response.contains("Swagger UI"));
|
||||||
|
assertTrue(response.contains("<div id=\"swagger-ui\"></div>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeOpenApi_thenCheckHeaders() {
|
||||||
|
ResponseEntity<String> response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
assertNotNull(response.getHeaders().get("Content-Type"));
|
||||||
|
assertEquals(1, response.getHeaders().get("Content-Type").size());
|
||||||
|
assertEquals("application/json", response.getHeaders().get("Content-Type").get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeOpenApi_thenVerifyOpenApiDoc() {
|
||||||
|
ResponseEntity<String> response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
assertTrue(response.getBody().contains("\"openapi\":"));
|
||||||
|
assertTrue(response.getBody().contains("Foos API"));
|
||||||
|
assertTrue(response.getBody().contains("\"post\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeOpenApi_thenCheckSecurityConfig() {
|
||||||
|
ResponseEntity<String> response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
assertTrue(response.getBody().contains("\"securitySchemes\""));
|
||||||
|
assertTrue(response.getBody().contains("\"type\":\"http\""));
|
||||||
|
assertTrue(response.getBody().contains("\"scheme\":\"basic\""));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.formlogin;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
class OpenAPIIntegrationTest {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeSwagger_thenRenderIndexPage() {
|
||||||
|
String response = this.restTemplate.getForObject("http://localhost:" + port + "/swagger-ui/index.html", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertTrue(response.contains("Swagger UI"));
|
||||||
|
assertTrue(response.contains("<div id=\"swagger-ui\"></div>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeOpenApi_thenCheckHeaders() {
|
||||||
|
ResponseEntity<String> response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
assertNotNull(response.getHeaders().get("Content-Type"));
|
||||||
|
assertEquals(1, response.getHeaders().get("Content-Type").size());
|
||||||
|
assertEquals("application/json", response.getHeaders().get("Content-Type").get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInvokeOpenApi_thenVerifyOpenApiDoc() {
|
||||||
|
ResponseEntity<String> response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs", String.class);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
assertTrue(response.getBody().contains("\"openapi\":"));
|
||||||
|
assertTrue(response.getBody().contains("Foos API"));
|
||||||
|
assertTrue(response.getBody().contains("\"post\""));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue