SpringDoc UI μΈμ¦μ μν ν ν° κΈ°λ³Έκ° νμ
Configure JWT Authentication for OpenAPIλ₯Ό μ°Έκ³ νλ©΄ SpringDoc UIλ₯Ό μ¬μ©ν λ JWT μΈμ¦μ μν΄ Bearer μ€ν€λ§ μ νμ ꡬμ±ν μ μμμ μ½κ² μ μ μλ€. κ·Έλ¬λ, Bearerμ κ°μ μΈμ¦ λ°©μμ κ²½μ° OAuth μλ λ€λ₯΄κ² κΈ°λ³Έκ°μ μ μ©ν μ μλ λ°©μμ΄ μλ€. μ€μ¨κ±° λ¬Έμμμ APIλ₯Ό νΈμΆν΄λ³΄κ³ μΆμ κ²½μ° λλΆλΆ μ€νλ§ μν리ν°μμ μ 곡νλ HTTP κΈ°λ³Έ μΈμ¦μ΄λ νΌ λ‘κ·ΈμΈμ νμ§ λͺ»νλλ‘ λΉνμ±ννκΈ° λλ¬Έμ μ¬μ©μ λ‘κ·ΈμΈμ μνν μ μλ μλν¬μΈνΈλ₯Ό λ§λ€μ΄μ λ¬Έμμ λ ΈμΆνμ¬ ν ν°μ λ°κΈν μ μλλ‘ ν΄μΌνλ€.
κΈ°λ³Έμ μΌλ‘ νλ‘μ νΈ κ°λ° μ Bearer μΈμ¦ μ Input λ°μ€μ κΈ°λ³Έκ°μ λ£μ΄λ λ°©μμ μμ΅λλ€.
SecurityScheme
@SecurityScheme(
name = "Bearer Authentication",
type = SecuritySchemeType.HTTP,
in = SecuritySchemeIn.HEADER,
bearerFormat = "JWT",
scheme = "bearer"
)
@Configuration
public class DocsConfig {}
μ λ§ν¬μμ Bearer Authentication
μ λν μ΄λ―Έμ§λ₯Ό μ μ΄ν΄λ³΄λ©΄ Description
μ΄ νμλλ κ±Έ νμΈν μ μλ€. μΈμ¦ λ°©λ²μ λν μ€λͺ
μ μ 곡νλ λΆλΆμ΄μ§λ§ μΌλ° ν
μ€νΈ λΏλ§ μλλΌ HTML νκ·Έκ° κ°λ₯ν κ²μΌλ‘ 보μΈλ€. λ³Έ κΈμμλ μ΄κ²μ μ΄μ©ν΄μ κ°λ° νκ²½μμλ ν
μ€νΈ μ¬μ©μμ λν μ΄λ¦κ³Ό ν ν°μ΄ νμλ μ μλλ‘ ν μμ μ΄λ€.
Customize SecurityScheme
@SecurityScheme
μ΄λ
Έν
μ΄μ
μΌλ‘ κΈλ‘λ² μΈμ¦μ λν μ€μ μ ꡬμ±νλ€λ©΄ OpenAPIλ₯Ό λΉμΌλ‘ λ±λ‘νλ ꡬμ±μΌλ‘ λ³κ²½μ΄ νμνλ€.
μλλ μ ν리μΌμ΄μ
μμ±μΌλ‘ λ±λ‘λ μ¬μ©μ ν ν° μ 보λ₯Ό Description μμμ νμλ μ μλλ‘ κ΅¬νν μμ μ΄λ€.
@Configuration
public class DocsConfig {
public static final String DEFAULT_AUTH = "JWT Authentication";
@Bean
public OpenAPI openAPI(BearerTokenProperties bearerTokenProperties) {
SecurityRequirement securityRequirement = new SecurityRequirement().addList(DEFAULT_AUTH);
SecurityScheme securityScheme = new SecurityScheme()
.name(DEFAULT_AUTH)
.type(SecurityScheme.Type.HTTP)
.in(SecurityScheme.In.HEADER)
.scheme("bearer")
.bearerFormat("JWT");
if (bearerTokenProperties.isEnabled() && !bearerTokenProperties.getTokens().isEmpty()) {
List<BearerTokenProperties.BearerToken> tokens = bearerTokenProperties.getTokens();
// NOTE: It is rendered as a markdown.
String description = tokens.stream()
.map(item -> String.format("**%s** %s", item.getName(), item.getToken()))
.collect(Collectors.joining("\n\n"));
securityScheme.description(description);
}
return new OpenAPI()
.addSecurityItem(securityRequirement)
.components(new Components()
.addSecuritySchemes(DEFAULT_AUTH, securityScheme));
}
}
@Getter
@ConstructorBinding
@RequiredArgsConstructor
@ConfigurationProperties("springdoc.bearer")
public class BearerTokenProperties {
private final boolean enabled;
private final List<BearerToken> tokens;
@Getter
@RequiredArgsConstructor
public static class BearerToken {
private final String name;
private final String token;
}
}
springdoc:
bearer:
enabled: on
tokens:
- name: Default
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- name: User2
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
μ°Έκ³ λ‘ μ μμ μ½λλ₯Ό 보면 λ§ν¬λ€μ΄ νμμΌλ‘ λ¬Έμμ΄μ ꡬμ±νλλ° κ°λ°μ λκ΅¬λ‘ Description μμμ μ΄ν΄λ³΄λ λ§ν¬λ€μ΄ λ λλ§μΌλ‘ λκ³ μμ΄μ κ΅³μ΄ HTML νκ·Έλ₯Ό μ¬μ©νμ§ μμμ΅λλ€. λ§ν¬λ€μ΄μ μ΅μνμ§ μλ κ°λ°μλΌλ©΄ μΌλ° HTML νκ·Έλ‘ λ§λμλ©΄ λ©λλ€.