Cara mengonfigurasi Keamanan Musim Semi untuk mengizinkan URL Swagger diakses tanpa autentikasi

92

Proyek saya memiliki Keamanan Musim Semi. Masalah utama: Tidak dapat mengakses URL swagger di http: // localhost: 8080 / api / v2 / api-docs . Tercantum header Otorisasi tidak ada atau tidak valid.

Tangkapan layar dari jendela browser My pom.xml memiliki entri berikut

<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", "[email protected]", "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/");
}

entri 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);
    }
}
shubhendu_shekhar
sumber

Jawaban:

176

Menambahkan ini ke kelas WebSecurityConfiguration Anda harus melakukan triknya.

@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/**");
    }

}
Stijn Maller
sumber
11
Jika Anda menggunakan swagger-ui, Anda memerlukan sesuatu seperti ini: .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
Dalam kasus saya, aturan ini berfungsi: .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
Memerlukan lebih banyak aturan: .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
Terima kasih atas jawabannya! Apakah ada risiko keamanan yang mengizinkan akses ke webjars / **?
ssimm
jawaban yang sangat membantu
Praveenkumar Beedanal
26

Saya memperbarui dengan / configuration / ** dan / swagger-resources / ** dan itu berhasil untuk saya.

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

}
Akshata Suvarna
sumber
Sempurna! Memecahkan masalah.
Madhu
24

Saya mengalami masalah yang sama saat menggunakan Spring Boot 2.0.0.M7 + Spring Security + Springfox 2.8.0. Dan saya memecahkan masalah menggunakan konfigurasi keamanan berikut yang memungkinkan akses publik ke sumber daya UI 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
    }

}
naXa
sumber
2
setelah menambahkan kelas ini, saya dapat melihat swagger-ui tetapi API tidak diakses melalui tukang pos bahkan dengan access_token, mendapatkan akses kesalahan terlarang seperti di bawah ini,{ "timestamp": 1519798917075, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/<some path>/shop" }
Chandrakant Audhutwar
@ChandrakantAudhutwar hapus antMatchers("/**").authenticated()pernyataan atau ganti dengan konfigurasi otentikasi Anda sendiri. Hati-hati, Anda lebih tahu apa yang Anda lakukan dengan keamanan.
naXa
ya, itu berhasil. Saya hanya berpikir untuk melewati swagger-ui, tetapi API lain yang diamankan. sekarang API saya juga dilewati.
Chandrakant Audhutwar
@ChandrakantAudhutwar Anda tidak perlu menyalin-tempel seluruh SecurityConfigurationkelas ke proyek Anda. Anda harus memiliki milik Anda sendiri di SecurityConfigurationmana Anda mengizinkan permintaan ke sumber daya UI Swagger dan menjaga keamanan API Anda.
naXa
Saya telah AuthorizationServerConfigurerAdaptermenerapkan kelas yang membuat otentikasi API.
Chandrakant Audhutwar
13

Bagi mereka yang menggunakan versi swagger 3 yang lebih baru 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/**");
    }
}
Dennis Glot
sumber
2
Catatan: Jika ini menghentikan Anda dari mendapatkan error "Diperlukan Autentikasi", tetapi hanya menampilkan halaman kosong, saya juga harus menambahkan "/ swagger-resources / **" dan "/ swagger-resources" dalam daftar itu dan masalah itu telah diperbaiki itu untukku.
Vinícius M
5

jika versi springfox Anda lebih tinggi dari 2.5 , harus menambahkan WebSecurityConfiguration seperti di bawah ini:

@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
sumber
duliu1990 benar, sejak springfox 2.5+, semua sumber daya springfox (termasuk kesombongan) telah dipindahkan /swagger-resources. /v2/api-docsadalah titik akhir api swagger default (tidak ada masalah dengan UI), yang dapat diganti dengan variabel config springfox.documentation.swagger.v2.path springfox
Mahieddine M. Ichir
3

Kurang lebih halaman ini memiliki jawaban tetapi semuanya tidak di satu tempat. Saya menghadapi masalah yang sama dan menghabiskan waktu yang cukup lama untuk itu. Sekarang saya memiliki pemahaman yang lebih baik dan saya ingin membagikannya di sini:

Saya Mengaktifkan ui Swagger dengan keamanan web Spring:

Jika Anda telah mengaktifkan Spring Websecurity secara default, Spring Websecurity akan memblokir semua permintaan ke aplikasi Anda dan mengembalikan 401. Namun untuk swagger ui dimuat di browser swagger-ui.html membuat beberapa panggilan untuk mengumpulkan data. Cara terbaik untuk men-debug adalah membuka swagger-ui.html di browser (seperti google chrome) dan menggunakan opsi pengembang (tombol 'F12'). Anda dapat melihat beberapa panggilan yang dilakukan saat halaman dimuat dan jika swagger-ui tidak dimuat sepenuhnya, mungkin beberapa di antaranya gagal.

Anda mungkin perlu memberi tahu Keamanan web Spring untuk mengabaikan autentikasi untuk beberapa pola jalur angkuh. Saya menggunakan swagger-ui 2.9.2 dan dalam kasus saya di bawah ini adalah pola yang harus saya abaikan:

Namun jika Anda menggunakan versi yang berbeda, versi Anda mungkin berubah. Anda mungkin harus mencari tahu milik Anda dengan opsi pengembang di browser Anda seperti yang saya katakan sebelumnya.

@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 Mengaktifkan ui kesombongan dengan interseptor

Umumnya Anda mungkin tidak ingin menghalangi permintaan yang dibuat oleh swagger-ui.html. Untuk mengecualikan beberapa pola kesombongan di bawah ini adalah kode:

Sebagian besar pola kasus untuk keamanan web dan interseptor akan sama.

@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/");
}

}

Karena Anda mungkin harus mengaktifkan @EnableWebMvc untuk menambahkan interseptor, Anda mungkin juga harus menambahkan penangan sumber daya ke swagger seperti yang telah saya lakukan pada cuplikan kode di atas.

chanderdevx.dll
sumber
Mengapa Anda menambahkan /csrfpengecualian?
Vishal
2

Membatasi hanya untuk resource terkait Swagger:

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

Berikut solusi lengkap untuk Swagger with Spring Security . Kami mungkin hanya ingin mengaktifkan Swagger di lingkungan pengembangan dan QA kami dan menonaktifkannya di lingkungan produksi. Jadi, saya menggunakan property ( prop.swagger.enabled) sebagai flag untuk melewati otentikasi keamanan musim semi untuk swagger-ui hanya di lingkungan pengembangan / 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/");
    }
  }
}
Abdul Rahman
sumber
1

Saya menggunakan Spring Boot 5. Saya memiliki pengontrol yang saya ingin pengguna tidak terautentikasi untuk dipanggil.

  //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();

Inilah yang saya lakukan dalam konfigurasi tersebut.

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

Semoga ini membantu....

smac2020
sumber
0

Mempertimbangkan semua permintaan API Anda yang terletak dengan pola url, /api/..Anda dapat memberitahu spring untuk mengamankan hanya pola url ini dengan menggunakan konfigurasi di bawah ini. Yang berarti bahwa Anda memberi tahu musim semi apa yang harus diamankan daripada apa yang harus diabaikan.

@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .csrf().disable()
     .authorizeRequests()
      .antMatchers("/api/**").authenticated()
      .anyRequest().permitAll()
      .and()
    .httpBasic().and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Siddu
sumber
1
Terima kasih atas cuplikan kode ini, yang mungkin memberikan beberapa bantuan jangka pendek terbatas. Penjelasan yang tepat akan sangat meningkatkan nilai jangka panjangnya dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah tersebut, dan akan membuatnya lebih berguna bagi pembaca di masa mendatang dengan pertanyaan serupa lainnya. Mohon edit jawaban Anda untuk menambahkan penjelasan, termasuk asumsi yang Anda buat.
Toby Speight