如何使用Keyclaok和Swagger实现Spring Boot Security OAuth2

问题描述 投票:0回答:1

我希望能够使用 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")));
    }

}

欢迎任何建议或教程链接,我尝试了我能找到的,但没有运气。

spring-security keycloak swagger-ui
1个回答
0
投票

根据我们在评论中的讨论,我认为您无法通过 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
按钮,就像您在邮递员中所做的那样,一切都会很好。

© www.soinside.com 2019 - 2024. All rights reserved.