2016-10-07 1 views
1

Ich möchte Sicherheitsdefinition zu meinem Rest Service mit org.apache.cxf.jaxrs.swagger.Swagger2Feature hinzufügen. Jedoch kann ich keine verwandte Methode oder irgendeine Ressource sehen, wie man es macht. Unten ist das Swagger-Dokument, das ich mit swagger2feature generieren möchte. Wie kann ich es tun?CXF Swagger2Feature hinzufügen securityDefinitions

swagger: '2.0' 
info: 
    version: 1.0.0 
    title: Based on "Basic Auth Example" 
    description: > 
    An example for how to use Auth with Swagger. 

host: basic-auth-server.herokuapp.com 
schemes: 
    - http 
    - https 
securityDefinitions: 
    Bearer: 
    type: apiKey 
    name: Authorization 
    in: header 
paths: 
    /: 
    get: 
     security: 
     - Bearer: [] 
     responses: 
     '200': 
      description: 'Will send `Authenticated`' 
     '403': 
      description: 'You do not have necessary permissions for the resource' 

Antwort

1

Ich war vor dem gleichen Problem und ich konnte nicht die passende Lösung mit CXF und seine api finden. Meine Lösung ist die folgende, erstellen Sie eine Klasse, die die Swagger2Feature von CXF erstreckt, um die addSwaggerResource Methode außer Kraft zu setzen, um gebunden, die Sicherheit Definition:

/** Name of the security definition */ 
public static final String SECURITY_NAME = "Bearer"; 

/** Extends the Swagger2Feature to use the security definition of Swagger */ 
@Provider(value = Provider.Type.Feature, scope = Provider.Scope.Server) 
public class ExtendedSwagger2Feature extends Swagger2Feature { 
    @Override 
    protected void addSwaggerResource(Server server, Bus bus) { 
     super.addSwaggerResource(server, bus); 

     BeanConfig config = (BeanConfig) ScannerFactory.getScanner(); 
     Swagger swagger = config.getSwagger(); 
     swagger.securityDefinition(SECURITY_NAME, new ApiKeyAuthDefinition("authorization", In.HEADER)); 
    } 
} 

Dann wird, wie die Swagger Instanz geändert wurde, nachdem es hat Von der Swagger API geladen, sollten Sie es im Kontext des Servlets "neu registrieren" (wie ich es verstehe, wenn ich den Code von Swagger durchsucht habe). Werfen Sie einen Blick auf io.swagger.jaxrs.config.SwaggerContextService. Um dies zu tun, ich hatte einen neuen ServletContextInitializer in meinem Servlet-Kontext zu erstellen:

return servletContext -> { 
    BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner(); 
    Swagger swagger = scanner.getSwagger(); 
    servletContext.setAttribute("swagger", swagger); 
}; 

im Rahmen Putting die Swagger Konfiguration zuvor mit der Sicherheitsdefinition geändert ermöglicht die Prahlerei api es zu berücksichtigen, richtig . Ohne dies würde unser erweitertes Swagger2Feature nicht funktionieren.

Mit diesen Änderungen konnte ich eine swagger.yaml Datei als eins bekommen, die Sie erwarten, vor allem der folgenden Teil:

securityDefinitions: 
    Bearer: 
    type: apiKey 
    name: Authorization 
    in: header 

Ich bin mit dieser Lösung in einer Frühlings-Boot-Anwendung, hier ist meine komplette Swagger-Konfiguration Klasse, falls es jemand hilft:

package my.package.configuration; 

import io.swagger.config.ScannerFactory; 
import io.swagger.core.filter.AbstractSpecFilter; 
import io.swagger.jaxrs.config.BeanConfig; 
import io.swagger.model.ApiDescription; 
import io.swagger.models.Operation; 
import io.swagger.models.Swagger; 
import io.swagger.models.auth.ApiKeyAuthDefinition; 
import io.swagger.models.auth.In; 
import org.apache.cxf.Bus; 
import org.apache.cxf.annotations.Provider; 
import org.apache.cxf.endpoint.Server; 
import org.apache.cxf.jaxrs.swagger.Swagger2Feature; 
import org.springframework.boot.web.servlet.ServletContextInitializer; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.DependsOn; 

import java.util.List; 
import java.util.Map; 

/** 
* Configuration of the Swagger API to enable it with CXF. 
*/ 
@Configuration 
public class SwaggerConfiguration { 

    /** Name of the security definition */ 
    public static final String SECURITY_NAME = "Bearer"; 

    @Bean 
    public Swagger2Feature swagger() { 
     Swagger2Feature feature = new ExtendedSwagger2Feature(); 
     // Do your stuff with the configuration 
     return feature; 
    } 

    /** 
    * Register a custom {@link ServletContextInitializer} in the cxf servlet to expose the custom {@link Swagger2Feature} 
    * otherwise the security definition added in the {@link ExtendedSwagger2Feature#addSwaggerResource} will not be 
    * used by the swagger api because the original hook occurs during the super call. 
    * 
    * @see io.swagger.jaxrs.config.SwaggerContextService 
    * @see org.apache.cxf.jaxrs.spring.SpringComponentScanServer 
    * 
    * @return a new instance of the {@link ServletContextInitializer} 
    */ 
    @Bean 
    @DependsOn("jaxRsServer") 
    public ServletContextInitializer initializer() { 
     return servletContext -> { 
      BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner(); 
      Swagger swagger = scanner.getSwagger(); 
      servletContext.setAttribute("swagger", swagger); 
     }; 
    } 

    /** 
    * Extension of the {@link Swagger2Feature} because the one provided by CXF doesn't allow to use 
    * feature of the Swagger API such as the security definition. This feature use the {@link ApiKeyAuthDefinition} 
    * to transport the authorization header required by the application. 
    */ 
    @Provider(value = Provider.Type.Feature, scope = Provider.Scope.Server) 
    public static class ExtendedSwagger2Feature extends Swagger2Feature { 
     @Override 
     protected void addSwaggerResource(Server server, Bus bus) { 
      super.addSwaggerResource(server, bus); 

      BeanConfig config = (BeanConfig) ScannerFactory.getScanner(); 
      Swagger swagger = config.getSwagger(); 
      swagger.securityDefinition(SECURITY_NAME, new ApiKeyAuthDefinition("authorization", In.HEADER)); 
     } 
    } 
} 
0

Ich benutze nicht Spring Boot, aber ich kopiert @ Naoj Ansatz. (Danke!)

Für diejenigen, die nicht im Spring Boot sind, können Sie dies in einem Start-Servlet erreichen, das nach dem CXF-Servlet geladen wird. Sie können auch vermeiden, die Klasse zu erweitern, wenn Sie die Swagger-Instanz nur ändern, wenn Sie sie greifen.

So in web.xml:

<servlet> 
    <servlet-name>SwaggerServlet</servlet-name> 
    <servlet-class>my.package.configuration.SwaggerStartupServlet</servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet> 

Dann wird der Servlet-Code:

/** Name of the security definition */ 
public static final String SECURITY_NAME = "Bearer"; 

@Override 
public void init(final ServletConfig config) throws ServletException 
{ 
    BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner(); 
    Swagger swagger = scanner.getSwagger(); 
    swagger.securityDefinition(SECURITY_NAME, new ApiKeyAuthDefinition("Authorization", In.HEADER)); 
    config.getServletContext().setAttribute("swagger", swagger); 
}