2017-07-13 21 views
0

私はSpringBoot、Jersey2、KeycloakでAPIを構築しています。私はSpringBootアダプタとSpringAdapterを使用しています。すべて順調。Keycloakで保護されたswagger.jsonを公開しようとしているAPI

は、私は今このページhttps://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5

つまずくそして、私のAPIについてswagger.jsonファイルを生成するために威張っコアパッケージを使用し始めました。 swagger-jersey2の依存関係により、swagger.jsonファイルがhttp://localhost:8080/swagger.jsonのようなリンクに公開されます。しかし、私はkeycloakがブロックするので、そのURLに一般公開することはできません。私SecurityConfigクラスで

私は、次の下にいる:

私は swagger.jsonは、ベアラ・トークンを渡すために必要とせずにアクセスできるように設定を変更するにはどうすればよい
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter 
{ 
    //....other code above 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     super.configure(http); 
     http.csrf().disable().authorizeRequests().antMatchers("*").permitAll(); 
     http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 
    } 
} 

?私は次のようにして、これを解決することになった

答えて

0

(私はトークンベアラとアクセステストし、それが働いていたが、私は、ベアラトークンなしでそれがアクセスできる必要があります):

  1. は新しいPubliResource注釈を作成します。
  2. PublicResourceで注釈付けされたクラスの起動時にリストを作成し、トークンが検出されなかった場合でも明示的にそれらのクラスを要求させるようにしました。
import java.lang.annotation.*; 

/*** 
* Used for marking a class accessible to a non-authorized user for 
* @GET, @PUT, @POST, and @DELETE annotations 
*/ 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@Inherited 
public @interface PublicResource { 

} 

それから私はAuthenticationTokenProcessingFilter豆を作りました。

import org.keycloak.KeycloakSecurityContext; 
import org.keycloak.adapters.AdapterUtils; 
import org.keycloak.adapters.RefreshableKeycloakSecurityContext; 
import org.keycloak.representations.AccessToken; 
import org.reflections.Reflections; 
import org.reflections.util.ConfigurationBuilder; 
import org.springframework.web.filter.GenericFilterBean; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.ws.rs.*; 
import java.io.IOException; 
import java.lang.reflect.Method; 
import java.util.Set; 
import java.util.TreeSet; 

public class AuthenticationTokenProcessingFilter extends GenericFilterBean { 

    private static Set<String> nonAuthenticationWhiteListSet = new TreeSet<>(); 

    static { 
     ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); 
     configurationBuilder.forPackages("com.package.code.resources"); //IMPORTANT 
     Reflections reflections = new Reflections(configurationBuilder); 
     Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(PublicResource.class); 
     for (Class<?> annotatedClass : annotated) { 
      if (!annotatedClass.isAnnotationPresent(Path.class)) { 
       continue; 
      } 
      String classPath = annotatedClass.getAnnotation(Path.class).value(); 

      for (Method method : annotatedClass.getDeclaredMethods()) { 
       String fullPath = classPath; 
       if (method.isAnnotationPresent(GET.class) 
         || method.isAnnotationPresent(POST.class) 
         || method.isAnnotationPresent(PUT.class) 
         || method.isAnnotationPresent(DELETE.class)) { 
        if (method.isAnnotationPresent(Path.class)) { 
         fullPath += method.getDeclaredAnnotation(Path.class).value(); 
        } 

        fullPath = fullPath.replaceAll("\\{.*\\}", "[^/]+"); 
        nonAuthenticationWhiteListSet.add(fullPath); 
       } 
      } 
     } 
    } 

    public AuthenticationTokenProcessingFilter() {} 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

     if (!(request instanceof HttpServletRequest)) { 
      throw new RuntimeException("Expecting a HTTP request"); 
     } 

     RefreshableKeycloakSecurityContext context = (RefreshableKeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); 

     if (context == null) { 
      handleNoSecurityContext(request, response, chain); 
      return; 
     } 

     chain.doFilter(request, response); 
    } 

    private void handleNoSecurityContext(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     String path = httpRequest.getPathInfo(); 

     if (isPublicResource(path)) { 
      chain.doFilter(request, response); 
      return; 
     } 

     ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     return; 
    } 

    private boolean isPublicResource(String path) { 
     for (String regex : nonAuthenticationWhiteListSet) { 
      if (path.matches(regex)) { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

私のメインクラスでは、これをフィルタとして登録するようにしました。

@Configuration 
@EnableAutoConfiguration(exclude = {FallbackWebSecurityAutoConfiguration.class, SpringBootWebSecurityConfiguration.class, DataSourceAutoConfiguration.class}) 
@ComponentScan 
@EnableAsync 
public class MyApi { 

    //...other code plus the main method 

    @Bean 
    public AuthenticationTokenProcessingFilter authFilter() { 
     return new AuthenticationTokenProcessingFilter(); 
    } 
} 
関連する問題