Keycloak integration in Swagger

前端 未结 3 1927
旧时难觅i
旧时难觅i 2020-12-23 19:40

I have a Keycloak protected backend that I would like to access via swagger-ui. Keycloak provides the oauth2 implicit and access code flow, but I was not able to make it wor

3条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-23 20:33

    Was struggling with this setup for the past 2 days. Finally got a working solution for those who cannot resolve.

    pom.xml

        ...
        
            org.keycloak
            keycloak-spring-security-adapter
        
        
            org.keycloak
            keycloak-spring-boot-starter
        
        ...
    

    Enable Swagger on main class

    ...    
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    @SpringBootApplication
    @EnableSwagger2
    @EnableAsync
    @EnableCaching
    public class MainApplication {
      public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MainApplication.class);
        app.run(args);
      }
    }
    

    SwaggerConfig.java

    package com.XXX.XXXXXXXX.app.config;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.AuthorizationCodeGrantBuilder;
    import springfox.documentation.builders.OAuthBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.service.*;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spi.service.contexts.SecurityContext;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger.web.SecurityConfiguration;
    import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    import java.util.Arrays;
    
    import static springfox.documentation.builders.PathSelectors.regex;
    
    /*
     * Setting up Swagger for spring boot
     * https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
     */
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
    
     @Value("${keycloak.auth-server-url}")
     private String AUTH_SERVER;
    
     @Value("${keycloak.credentials.secret}")
     private String CLIENT_SECRET;
    
     @Value("${keycloak.resource}")
     private String CLIENT_ID;
    
     @Value("${keycloak.realm}")
     private String REALM;
    
     private static final String OAUTH_NAME = "spring_oauth";
     private static final String ALLOWED_PATHS = "/directory_to_controllers/.*";
     private static final String GROUP_NAME = "XXXXXXX-api";
     private static final String TITLE = "API Documentation for XXXXXXX Application";
     private static final String DESCRIPTION = "Description here";
     private static final String VERSION = "1.0";
    
     @Bean
     public Docket taskApi() {
       return new Docket(DocumentationType.SWAGGER_2)
        .groupName(GROUP_NAME)
        .useDefaultResponseMessages(true)
        .apiInfo(apiInfo())
        .select()
        .paths(regex(ALLOWED_PATHS))
        .build()
        .securitySchemes(Arrays.asList(securityScheme()))
        .securityContexts(Arrays.asList(securityContext()));
     }
    
     private ApiInfo apiInfo() {
       return new 
         ApiInfoBuilder().title(TITLE).description(DESCRIPTION).version(VERSION).build();
     }
    
     @Bean
     public SecurityConfiguration security() {
       return SecurityConfigurationBuilder.builder()
        .realm(REALM)
        .clientId(CLIENT_ID)
        .clientSecret(CLIENT_SECRET)
        .appName(GROUP_NAME)
        .scopeSeparator(" ")
        .build();
     }
    
     private SecurityScheme securityScheme() {
       GrantType grantType =
        new AuthorizationCodeGrantBuilder()
            .tokenEndpoint(new TokenEndpoint(AUTH_SERVER + "/realms/" + REALM + "/protocol/openid-connect/token", GROUP_NAME))
            .tokenRequestEndpoint(
                new TokenRequestEndpoint(AUTH_SERVER + "/realms/" + REALM + "/protocol/openid-connect/auth", CLIENT_ID, CLIENT_SECRET))
            .build();
    
    SecurityScheme oauth =
        new OAuthBuilder()
            .name(OAUTH_NAME)
            .grantTypes(Arrays.asList(grantType))
            .scopes(Arrays.asList(scopes()))
            .build();
    return oauth;
     }
    
     private AuthorizationScope[] scopes() {
    AuthorizationScope[] scopes = {
      new AuthorizationScope("user", "for CRUD operations"),
      new AuthorizationScope("read", "for read operations"),
      new AuthorizationScope("write", "for write operations")
    };
    return scopes;
    }
    
    private SecurityContext securityContext() {
    return SecurityContext.builder()
        .securityReferences(Arrays.asList(new SecurityReference(OAUTH_NAME, scopes())))
        .forPaths(PathSelectors.regex(ALLOWED_PATHS))
        .build();
     }
    }
    

    From terminal, run "mvnw spring-boot:run"

    Open browser and hit http://localhost:[port]/[app_name]/swagger-ui.html.

    Click the Authorize button: Swagger Authorize Button

    This should present a modal to confirm your keycloak settings.

    Click Authorize button once again. You should be redirected to a login screen.

    Once credentials are entered and confirmed, you will be redirected back to Swagger-UI fully authenticated.

提交回复
热议问题