* BAEL-5328

First draft of the code to the article:
https://drafts.baeldung.com/wp-admin/post.php?post=136328&action=edit

* BAEL-5328

Fixed comment. Used  entry point instead of endpoint

* BAEL-5328

Added SecurityFilterChain configuration to allow requests to:
* "/api/auth/**", "/swagger-ui-custom.html" ,"/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/webjars/**", "/swagger-ui/index.html","/api-docs/**"
As the spring-boot-starter-security has been started we need to add it to keep this article, simple.
Fixed description of the login() method for the 200 httpstatus response

* BAEL-5328

Added required attribute in @RequestBody of the login() method

* BAEL-5328

Code formatting
This commit is contained in:
victorsempere 2022-07-25 05:51:00 +02:00 committed by GitHub
parent 7a44c4ff3e
commit a4691406f2
6 changed files with 363 additions and 0 deletions

View File

@ -0,0 +1,32 @@
package com.baeldung.defaultglobalsecurityscheme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
@SpringBootApplication
@OpenAPIDefinition(info = @Info(title = "Apply Default Global SecurityScheme in springdoc-openapi", version = "1.0.0"), security = { @SecurityRequirement(name = "api_key") })
@SecurityScheme(type = SecuritySchemeType.APIKEY, name = "api_key", in = SecuritySchemeIn.HEADER)
public class DefaultGlobalSecuritySchemeApplication {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.antMatchers("/api/auth/**", "/swagger-ui-custom.html", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/webjars/**", "/swagger-ui/index.html", "/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.build();
}
public static void main(String[] args) {
SpringApplication.run(DefaultGlobalSecuritySchemeApplication.class, args);
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.defaultglobalsecurityscheme.controller;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import javax.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.defaultglobalsecurityscheme.dto.LoginDto;
import com.baeldung.defaultglobalsecurityscheme.dto.ApplicationExceptionDto;
import com.baeldung.defaultglobalsecurityscheme.dto.PingResponseDto;
import com.baeldung.defaultglobalsecurityscheme.dto.TokenDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
@RestController
@RequestMapping("/")
public class DefaultGlobalSecuritySchemeOpenApiController {
@RequestMapping(method = RequestMethod.POST, value = "/login", produces = { "application/json" }, consumes = { "application/json" })
@Operation(operationId = "login", responses = {
@ApiResponse(responseCode = "200", description = "api_key to be used in the secured-ping entry point", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = TokenDto.class)) }),
@ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) })
@SecurityRequirements()
public ResponseEntity<TokenDto> login(@Parameter(name = "LoginDto", description = "Login") @Valid @RequestBody(required = true) LoginDto loginDto) {
TokenDto token = new TokenDto();
token.setRaw("Generated Token");
return ResponseEntity.ok(token);
}
@Operation(operationId = "ping", responses = {
@ApiResponse(responseCode = "200", description = "Ping that needs an api_key attribute in the header", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = PingResponseDto.class), examples = { @ExampleObject(value = "{ pong: '2022-06-17T18:30:33.465+02:00' }") }) }),
@ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }),
@ApiResponse(responseCode = "403", description = "Forbidden request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) })
@RequestMapping(method = RequestMethod.GET, value = "/ping", produces = { "application/json" })
public ResponseEntity<PingResponseDto> ping(@RequestHeader(name = "api_key", required = false) String api_key) {
int year = 2000;
int month = 1;
int dayOfMonth = 1;
int hour = 0;
int minute = 0;
int second = 0;
int nanoSeccond = 0;
ZoneOffset offset = ZoneOffset.UTC;
PingResponseDto response = new PingResponseDto();
response.setPong(OffsetDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoSeccond, offset));
return ResponseEntity.ok(response);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.defaultglobalsecurityscheme.dto;
public class ApplicationExceptionDto {
private long errorCode;
private String description;
public ApplicationExceptionDto() {
super();
}
public long getErrorCode() {
return errorCode;
}
public void setErrorCode(long errorCode) {
this.errorCode = errorCode;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,103 @@
package com.baeldung.defaultglobalsecurityscheme.dto;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* LoginDto
*/
@JsonTypeName("Login")
public class LoginDto {
@JsonProperty("user")
private String user;
@JsonProperty("pass")
private String pass;
public LoginDto user(String user) {
this.user = user;
return this;
}
/**
* Get user
* @return user
*/
@Schema(name = "user", required = true)
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public LoginDto pass(String pass) {
this.pass = pass;
return this;
}
/**
* Get pass
* @return pass
*/
@Schema(name = "pass", required = true)
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LoginDto login = (LoginDto) o;
return Objects.equals(this.user, login.user) && Objects.equals(this.pass, login.pass);
}
@Override
public int hashCode() {
return Objects.hash(user, pass);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class LoginDto {\n");
sb.append(" user: ")
.append(toIndentedString(user))
.append("\n");
sb.append(" pass: ")
.append(toIndentedString(pass))
.append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString()
.replace("\n", "\n ");
}
}

View File

@ -0,0 +1,84 @@
package com.baeldung.defaultglobalsecurityscheme.dto;
import java.time.OffsetDateTime;
import java.util.Objects;
import javax.validation.Valid;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* SecuredPingResponseDto
*/
@JsonTypeName("PingResponse")
public class PingResponseDto {
@JsonProperty("pong")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private OffsetDateTime pong;
public PingResponseDto pong(OffsetDateTime pong) {
this.pong = pong;
return this;
}
/**
* Get pong
* @return pong
*/
@Valid
@Schema(name = "pong", required = false)
public OffsetDateTime getPong() {
return pong;
}
public void setPong(OffsetDateTime pong) {
this.pong = pong;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PingResponseDto securedPingResponse = (PingResponseDto) o;
return Objects.equals(this.pong, securedPingResponse.pong);
}
@Override
public int hashCode() {
return Objects.hash(pong);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class PingResponseDto {\n");
sb.append(" pong: ")
.append(toIndentedString(pong))
.append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString()
.replace("\n", "\n ");
}
}

View File

@ -0,0 +1,57 @@
package com.baeldung.defaultglobalsecurityscheme.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* LoginDto
*/
@JsonTypeName("Token")
public class TokenDto {
@JsonProperty("raw")
private String raw;
@Schema(name = "raw", example = "app token")
public String getRaw() {
return raw;
}
public void setRaw(String raw) {
this.raw = raw;
}
@Override
public String toString() {
return "TokenDto [raw=" + raw + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((raw == null) ? 0 : raw.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TokenDto other = (TokenDto) obj;
if (raw == null) {
if (other.raw != null)
return false;
} else if (!raw.equals(other.raw))
return false;
return true;
}
}