BAEL-5328 (#12457)
* 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:
parent
7a44c4ff3e
commit
a4691406f2
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 ");
|
||||
}
|
||||
}
|
@ -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 ");
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user