Como configurar o Spring Security para permitir que o URL do Swagger seja acessado sem autenticação


97

Meu projeto tem Spring Security. Problema principal: Não é possível acessar o URL swagger em http: // localhost: 8080 / api / v2 / api-docs . Ele diz Cabeçalho de autorização ausente ou inválido.

Captura de tela da janela do navegador Meu pom.xml contém as seguintes entradas

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.4.0</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
</dependency>

SwaggerConfig:

@Configuration
@EnableSwagger2
public class SwaggerConfig {

@Bean
public Docket api() {
    return new Docket(DocumentationType.SWAGGER_2).select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build()
            .apiInfo(apiInfo());
}

private ApiInfo apiInfo() {
    ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", "myeaddress@company.com", "License of API", "API license URL");
    return apiInfo;
}

AppConfig:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.musigma.esp2" })
@Import(SwaggerConfig.class)
public class AppConfig extends WebMvcConfigurerAdapter {

// ========= Overrides ===========

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LocaleChangeInterceptor());
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("swagger-ui.html")
      .addResourceLocations("classpath:/META-INF/resources/");

    registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/");
}

Entradas web.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        com.musigma.esp2.configuration.AppConfig
        com.musigma.esp2.configuration.WebSecurityConfiguration
        com.musigma.esp2.configuration.PersistenceConfig
        com.musigma.esp2.configuration.ACLConfig
        com.musigma.esp2.configuration.SwaggerConfig
    </param-value>
</context-param>

WebSecurityConfig:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = { "com.musigma.esp2.service", "com.musigma.esp2.security" })
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
        .csrf()
            .disable()
        .exceptionHandling()
            .authenticationEntryPoint(this.unauthorizedHandler)
            .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .authorizeRequests()
            .antMatchers("/auth/login", "/auth/logout").permitAll()
            .antMatchers("/api/**").authenticated()
            .anyRequest().authenticated();

        // custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
        httpSecurity.addFilterBefore(loginFilter(), UsernamePasswordAuthenticationFilter.class);

        // custom Token based authentication based on the header previously given to the client
        httpSecurity.addFilterBefore(new StatelessTokenAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class);
    }
}

Respostas:


180

Adicionar isso à sua classe WebSecurityConfiguration deve resolver o problema.

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs",
                                   "/configuration/ui",
                                   "/swagger-resources/**",
                                   "/configuration/security",
                                   "/swagger-ui.html",
                                   "/webjars/**");
    }

}

11
Se você usar o swagger-ui, você precisará de algo como isto: .antMatchers ("/ v2 / api-docs", "/ configuration / ui", "/ swagger-resources", "/ configuration / security", "/ swagger-ui .html "," / webjars / ** "," / swagger-resources / configuration / ui "," / swagger-ui.html "). permitAll ()
— Daniel Martín

2
No meu caso, esta regra está funcionando: .antMatchers ("/ v2 / api-docs", "/ configuration / ui", "/ swagger-resources", "/ configuration / security", "/swagger-ui.html", "/ webjars / **", "/ swagger-resources / configuration / ui", "/ swagge‌ r-ui.html", "/ swagger-resources / configuration / security"). permitAll ()
— nikolai.serdiuk

6
Mais regras necessárias: .antMatchers ("/", "/ csrf", "/ v2 / api-docs", "/ swagger-resources / configuration / ui", "/ configuration / ui", "/ swagger-resources", "/ swagger-resources / configuration / security", "/ configuration / security", "/swagger-ui.html", "/ webjars / **"). permitAll ()
— Mate Šimović

5
Obrigado pela resposta! Existe algum risco de segurança ao permitir o acesso a webjars / **?
— ssimm

resposta muito útil
— Praveenkumar Beedanal 01 de

26

Eu atualizei com / configuration / ** e / swagger-resources / ** e funcionou para mim.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html", "/webjars/**");

}

Perfeito! Resolvido o problema.
— Madhu

25

Eu tive o mesmo problema ao usar Spring Boot 2.0.0.M7 + Spring Security + Springfox 2.8.0. E resolvi o problema usando a seguinte configuração de segurança que permite o acesso público aos recursos da IU do Swagger.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**"
            // other public endpoints of your API may be appended to this array
    };


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                // ... here goes your custom security configuration
                authorizeRequests().
                antMatchers(AUTH_WHITELIST).permitAll().  // whitelist Swagger UI resources
                // ... here goes your custom security configuration
                antMatchers("/**").authenticated();  // require authentication for any endpoint that's not whitelisted
    }

}

2
depois de adicionar esta classe, posso ver o swagger-ui, mas as APIs não são acessadas via carteiro mesmo com access_token, obtendo o erro de acesso proibido conforme abaixo,{ "timestamp": 1519798917075, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/<some path>/shop" }
— Chandrakant Audhutwar

@ChandrakantAudhutwar delete a antMatchers("/**").authenticated()instrução ou substitua por sua própria configuração de autenticação. Cuidado, é melhor você saber o que está fazendo com segurança.
— naXa

sim, funcionou. Eu estava pensando em apenas ignorar o swagger-ui, mas outras APIs, pois é seguro. agora minhas APIs também são ignoradas.
— Chandrakant Audhutwar

@ChandrakantAudhutwar você não precisa copiar e colar a SecurityConfigurationclasse inteira em seu projeto. Você deve ter seu próprio, SecurityConfigurationonde permitir solicitações para recursos de IU do Swagger e manter suas APIs seguras.
— naXa

Eu AuthorizationServerConfigurerAdapterimplementei uma classe que faz a autenticação da API.
— Chandrakant Audhutwar

14

Para aqueles que usam uma versão mais recente do swagger 3 org.springdoc:springdoc-openapi-ui

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**");
    }
}

2
Observação: se isso impedisse que você recebesse um erro "Autenticação necessária", mas apenas mostrasse uma página em branco, também tive que adicionar "/ swagger-resources / **" e "/ swagger-resources" nessa lista e corrigiu isso para mim.
— Vinícius M

6

se a sua versão springfox superior a 2.5, deve ser adicionado WebSecurityConfiguration como abaixo:

@Override
public void configure(HttpSecurity http) throws Exception {
    // TODO Auto-generated method stub
    http.authorizeRequests()
        .antMatchers("/v2/api-docs", "/swagger-resources/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .csrf().disable();
}

duliu1990 está certo, desde o springfox 2.5+, todos os recursos do springfox (swagger incluído) foram movidos /swagger-resources. /v2/api-docsé o ponto de extremidade de api swagger padrão (sem preocupação com a IU), que pode ser substituído pela variável de configuração springfox.documentation.swagger.v2.path springfox
— Mahieddine M. Ichir

4

Mais ou menos esta página tem respostas, mas nem todas estão no mesmo lugar. Eu estava lidando com o mesmo problema e gastei um bom tempo nisso. Agora compreendo melhor e gostaria de compartilhar aqui:

I Habilitando Swagger ui com Spring websecurity:

Se você habilitou o Spring Websecurity por padrão, ele bloqueará todas as solicitações do seu aplicativo e retornará 401. No entanto, para que o swagger ui seja carregado no navegador, swagger-ui.html faz várias chamadas para coletar dados. A melhor maneira de depurar é abrir swagger-ui.html em um navegador (como o google chrome) e usar as opções do desenvolvedor (tecla 'F12'). Você pode ver várias chamadas feitas quando a página carrega e se o swagger-ui não estiver carregando completamente, provavelmente algumas delas estão falhando.

você pode precisar dizer ao Spring websecurity para ignorar a autenticação para vários padrões de caminho swagger. Estou usando o swagger-ui 2.9.2 e, no meu caso, abaixo estão os padrões que tive que ignorar:

No entanto, se você estiver usando uma versão diferente, a sua pode mudar. você pode ter que descobrir o seu com a opção de desenvolvedor em seu navegador, como eu disse antes.

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", 
            "/swagger-resources/**", "/configuration/**", "/swagger-ui.html"
            , "/webjars/**", "/csrf", "/");
}
}

II Habilitando swagger ui com interceptor

Geralmente, você não pode querer interceptar solicitações feitas por swagger-ui.html. Para excluir vários padrões de arrogância abaixo está o código:

A maioria dos casos padrão para segurança da web e interceptor será o mesmo.

@Configuration
@EnableWebMvc
public class RetrieveCiamInterceptorConfiguration implements WebMvcConfigurer {

@Autowired
RetrieveInterceptor validationInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {

    registry.addInterceptor(validationInterceptor).addPathPatterns("/**")
    .excludePathPatterns("/v2/api-docs", "/configuration/ui", 
            "/swagger-resources/**", "/configuration/**", "/swagger-ui.html"
            , "/webjars/**", "/csrf", "/");
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("swagger-ui.html")
      .addResourceLocations("classpath:/META-INF/resources/");

    registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/");
}

}

Já que você pode ter que habilitar @EnableWebMvc para adicionar interceptores, você também pode ter que adicionar manipuladores de recursos para swagger semelhante ao que fiz no trecho de código acima.


Por que você está adicionando /csrfexclusão?
— Vishal

2

Limitando apenas a recursos relacionados ao Swagger:

.antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/springfox-swagger-ui/**");

2

Aqui está uma solução completa para Swagger com Spring Security . Provavelmente, queremos ativar o Swagger apenas em nosso ambiente de desenvolvimento e controle de qualidade e desativá-lo no ambiente de produção. Portanto, estou usando um property ( prop.swagger.enabled) como um sinalizador para ignorar a autenticação de segurança do spring para swagger-ui apenas no ambiente de desenvolvimento / qa.

@Configuration
@EnableSwagger2
public class SwaggerConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {

@Value("${prop.swagger.enabled:false}")
private boolean enableSwagger;

@Bean
public Docket SwaggerConfig() {
    return new Docket(DocumentationType.SWAGGER_2)
            .enable(enableSwagger)
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.your.controller"))
            .paths(PathSelectors.any())
            .build();
}

@Override
public void configure(WebSecurity web) throws Exception {
    if (enableSwagger)  
        web.ignoring().antMatchers("/v2/api-docs",
                               "/configuration/ui",
                               "/swagger-resources/**",
                               "/configuration/security",
                               "/swagger-ui.html",
                               "/webjars/**");
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (enableSwagger) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
  }
}

1

Estou usando o Spring Boot 5. Tenho este controlador que desejo que um usuário não autenticado invoque.

  //Builds a form to send to devices   
@RequestMapping(value = "/{id}/ViewFormit", method = RequestMethod.GET)
@ResponseBody
String doFormIT(@PathVariable String id) {
    try
    {
        //Get a list of forms applicable to the current user
        FormService parent = new FormService();

Aqui está o que eu fiz na configuração.

  @Override
   protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers(
                    "/registration**",
                    "/{^[\\\\d]$}/ViewFormit",

Espero que isto ajude....


1

Alguma configuração de segurança e você está pronto com arrogância aberta para todos

Para Swagger V2

@Configuration
@EnableWebSecurity
public class CabSecurityConfig extends WebSecurityConfigurerAdapter {


    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/v2/api-docs", 
            "/swagger-resources/**", 
            "/configuration/ui",
            "/configuration/security", 
            "/swagger-ui.html",
            "/webjars/**"
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // ... here goes your custom security configuration
        http.authorizeRequests().
        antMatchers(AUTH_WHITELIST).permitAll(). // whitelist URL permitted
        antMatchers("/**").authenticated(); // others need auth
    }

}

Para Swagger V3

@Configuration
@EnableWebSecurity
public class CabSecurityConfig extends WebSecurityConfigurerAdapter {


    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/v2/api-docs",
            "/v3/api-docs",  
            "/swagger-resources/**", 
            "/swagger-ui/**",
             };

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // ... here goes your custom security configuration
        http.authorizeRequests().
        antMatchers(AUTH_WHITELIST).permitAll(). // whitelist URL permitted
        antMatchers("/**").authenticated(); // others need auth
    }

}

0

Considerando todas as suas solicitações de API localizadas com um padrão de url de, /api/..você pode dizer ao Spring para proteger apenas esse padrão de url usando a configuração abaixo. O que significa que você está dizendo a spring o que proteger em vez do que ignorar.

@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .csrf().disable()
     .authorizeRequests()
      .antMatchers("/api/**").authenticated()
      .anyRequest().permitAll()
      .and()
    .httpBasic().and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

1
Obrigado por este trecho de código, que pode fornecer alguma ajuda limitada de curto prazo. Uma explicação adequada melhoraria muito seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema, e a tornaria mais útil para futuros leitores com outras questões semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
— Toby Speight,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.