我希望能够使用 Keycloak 和 Spring Boot Security 通过 Swagger UI 登录。到目前为止,我可以通过邮递员使用不记名生成的令牌登录,但是如何配置用户凭据登录?
安全配置:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private static final String[] AUTH_WHITELIST = {"/swagger-resources", "/swagger-resources/**", "/configuration/ui",
"/configuration/security", "/swagger-ui.html", "/webjars/**", "/v3/api-docs/**", "v3/api-docs",
"/api/public/**", "/api/public/authenticate", "/actuator/*", "/swagger-ui/**", "/api-docs/**"};
private final JwtAuthConverter jwtAuthConverter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable());
http.authorizeHttpRequests(auth -> auth.requestMatchers(AUTH_WHITELIST).permitAll().anyRequest().authenticated());
http.oauth2ResourceServer(o2 -> o2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthConverter)));
http.sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
}
转换器:
@Component
public class JwtAuthConverter implements Converter<Jwt, AbstractAuthenticationToken> {
private final JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
@Value("${jwt.auth.converter.principle_attribute}")
private String principleAttribute;
@Value("${jwt.auth.converter.resource-id}")
private String resourceId;
@Override
public AbstractAuthenticationToken convert(@NonNull Jwt jwt) {
Collection<GrantedAuthority> authorities = Stream.concat(jwtGrantedAuthoritiesConverter.convert(jwt).stream(), extractResourceRoles(jwt).stream()).collect(Collectors.toSet());
return new JwtAuthenticationToken(jwt, authorities, getPrincipleClaimName(jwt));
}
private String getPrincipleClaimName(Jwt jwt) {
String claimName = JwtClaimNames.SUB;
if (principleAttribute != null) {
claimName = principleAttribute;
}
return jwt.getClaim(claimName);
}
private Collection<? extends GrantedAuthority> extractResourceRoles(Jwt jwt) {
Map<String, Object> resourceAccess;
Map<String, Object> resource;
Collection<String> resourceRoles;
if (jwt.getClaim("resource_access") == null) {
return Set.of();
}
resourceAccess = jwt.getClaim("resource_access");
if (resourceAccess.get(resourceId) == null) {
return Set.of();
}
resource = (Map<String, Object>) resourceAccess.get(resourceId);
resourceRoles = (Collection<String>) resource.get("roles");
return resourceRoles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toSet());
}
}
Swagger 配置:
@Configuration
public class SwaggerConfig {
private static final String OAUTH_SCHEME_BEARER = "bearerAuth";
@Bean
public OpenAPI customizeOpenAPI() {
return new OpenAPI()
.addSecurityItem(new SecurityRequirement()
.addList(OAUTH_SCHEME_BEARER))
.components(new Components()
.addSecuritySchemes(OAUTH_SCHEME_BEARER, new SecurityScheme()
.name(OAUTH_SCHEME_BEARER)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
}
欢迎任何建议或教程链接,我尝试了我能找到的,但没有运气。
根据我们在评论中的讨论,我认为您无法通过 swagger 访问应用程序的端点,并且根据您提供的代码,我可以说您应该更改您的 swagger 配置:
类似这样的:
OpenApi配置类
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI myAPI() {
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("bearer-key",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
)
)
.info(getApiInfo())
.addSecurityItem(
new SecurityRequirement()
.addList("bearer-jwt", Arrays.asList("read", "write"))
.addList("bearer-key", Collections.emptyList())
);
}
private Info getApiInfo() {
return new Info()
.title("Application Backend API")
.description("APIS")
.version("version")
.contact(getContacts())
.license(new License().name("Apache 2.0").url("http://springdoc.org"));
}
private Contact getContacts() {
return new Contact()
.name("app name")
.url("url")
.email("mail");
}
}
在其之后,如果您将打开 api url(
...swagger-ui/index.html
) 并在插入您的 Authorize
令牌后单击 JWT
按钮,就像您在邮递员中所做的那样,一切都会很好。