如何配置Spring Boot+Keycloak实现Swagger UI账号密码登录
问题描述
我希望通过Swagger UI结合Keycloak与Spring Boot Security实现账号密码登录。目前已能通过Postman使用生成的Bearer Token完成接口调用,但不清楚如何配置Swagger UI支持用户直接输入账号密码登录的方式。
现有配置代码
Security配置:
@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(); } }
JwtAuthConverter转换器:
@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"))); } }
配置解决方案
1. 修改Swagger配置,支持OAuth2 Password Flow
替换原Swagger配置,添加OAuth2密码模式支持,让Swagger UI可以直接调用Keycloak令牌接口获取Bearer Token:
@Configuration public class SwaggerConfig { private static final String OAUTH_SCHEME_OAUTH2 = "oauth2"; @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") private String issuerUri; @Bean public OpenAPI customizeOpenAPI() { // 构建OAuth2密码流配置 OAuthFlow oAuthFlow = new OAuthFlow() .tokenUrl(issuerUri + "/protocol/openid-connect/token") .scopes(new Scopes().addString("openid", "OpenID Connect scope")); // 可根据需求添加其他scope SecurityScheme securityScheme = new SecurityScheme() .name(OAUTH_SCHEME_OAUTH2) .type(SecurityScheme.Type.OAUTH2) .flows(new OAuthFlows().password(oAuthFlow)); return new OpenAPI() .addSecurityItem(new SecurityRequirement().addList(OAUTH_SCHEME_OAUTH2)) .components(new Components().addSecuritySchemes(OAUTH_SCHEME_OAUTH2, securityScheme)); } }
2. 配置Swagger UI的OAuth客户端参数
在application.yml或application.properties中添加以下配置:
springdoc: swagger-ui: oauth: client-id: your-keycloak-client-id # 替换为你的Keycloak客户端ID client-secret: your-keycloak-client-secret # 替换为Keycloak客户端密钥(保密类型客户端需配置) use-pkce-with-authorization-code-grant: false # 密码流无需PKCE
3. 调整Keycloak客户端配置
在Keycloak控制台中找到目标客户端,完成以下配置:
- 开启Direct Access Grants Enabled(允许密码模式)
- 根据需求设置Access Type为
confidential或public - 确保有效重定向URI包含Swagger UI地址,例如
http://localhost:8080/swagger-ui/**
4. 验证Security配置
现有AUTH_WHITELIST已覆盖Swagger相关路径,无需额外修改。
完成上述配置后,启动应用访问Swagger UI(默认地址http://localhost:8080/swagger-ui.html),点击右上角Authorize按钮,输入Keycloak用户名、密码及客户端信息,即可自动获取令牌并携带到接口请求中。
内容的提问来源于stack exchange,提问作者M G
相关产品推荐
相关产品推荐

