วิธีกำหนดค่า Spring Security เพื่อให้สามารถเข้าถึง Swagger URL ได้โดยไม่ต้องตรวจสอบสิทธิ์


92

โครงการของฉันมี Spring Security ปัญหาหลัก: ไม่สามารถเข้าถึง URL ผยองที่http: // localhost: 8080 / API / v2 / API-เอกสาร มันขึ้นว่า Missing or invalid Authorization header

ภาพหน้าจอของหน้าต่างเบราว์เซอร์ My pom.xml มีรายการดังต่อไปนี้

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

รายการ 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);
    }
}

คำตอบ:


176

การเพิ่มสิ่งนี้ในคลาส WebSecurityConfiguration ของคุณควรทำเคล็ดลับ

@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
หากคุณใช้ swagger-ui คุณต้องการสิ่งนี้: .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
ในกรณีของฉันกฎนี้ใช้งานได้: .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
ต้องการกฎเพิ่มเติม: .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
ขอบคุณสำหรับคำตอบ! มีความเสี่ยงด้านความปลอดภัยที่อนุญาตให้เข้าถึงเว็บจาร์ / ** หรือไม่?
ssimm

คำตอบที่เป็นประโยชน์มาก
Praveenkumar Beedanal

26

ฉันอัปเดตด้วย / configuration / ** และ / swagger-resources / ** และมันก็ใช้ได้สำหรับฉัน

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

}

สมบูรณ์แบบ! แก้ไขปัญหาแล้ว
Madhu

24

ฉันมีปัญหาเดียวกันในการใช้ Spring Boot 2.0.0.M7 + Spring Security + Springfox 2.8.0 และฉันแก้ไขปัญหาโดยใช้การกำหนดค่าความปลอดภัยต่อไปนี้ที่อนุญาตให้เข้าถึงทรัพยากร Swagger UI แบบสาธารณะ

@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
หลังจากเพิ่มคลาสนี้ฉันสามารถมองเห็น swagger-ui ได้ แต่ API ไม่สามารถเข้าถึงได้ผ่านบุรุษไปรษณีย์แม้ว่าจะมี access_token ก็ตามการเข้าถึงข้อผิดพลาดที่ต้องห้ามดังต่อไปนี้{ "timestamp": 1519798917075, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/<some path>/shop" }
Chandrakant Audhutwar

@ChandrakantAudhutwar ลบantMatchers("/**").authenticated()คำสั่งหรือแทนที่ด้วยการกำหนดค่าการพิสูจน์ตัวตนของคุณเอง ระวังคุณจะรู้ดีกว่าว่าคุณกำลังทำอะไรกับความปลอดภัย
naXa

ใช่มันได้ผล ฉันคิดว่าจะข้ามแค่ swagger-ui แต่ API อื่น ๆ ก็ปลอดภัยแล้ว ตอนนี้ API ของฉันถูกข้ามด้วย
Chandrakant Audhutwar

@ChandrakantAudhutwar คุณไม่จำเป็นต้องคัดลอกและวางทั้งSecurityConfigurationชั้นเรียนลงในโครงการของคุณ คุณควรมีของคุณเองSecurityConfigurationที่อนุญาตการร้องขอทรัพยากร Swagger UI และรักษา API ของคุณให้ปลอดภัย
naXa

ฉันได้AuthorizationServerConfigurerAdapterใช้คลาสที่ทำให้การรับรองความถูกต้องของ API
Chandrakant Audhutwar

13

สำหรับผู้ที่ใช้ 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
หมายเหตุ: หากสิ่งนี้ทำให้คุณไม่ได้รับข้อผิดพลาด "จำเป็นต้องมีการตรวจสอบสิทธิ์" แต่เพียงแค่แสดงหน้าว่างฉันต้องเพิ่ม "/ swagger-resources / **" และ "/ swagger-resources" ในรายการนั้นด้วยและได้รับการแก้ไข สำหรับฉัน
Vinícius M

5

หากเวอร์ชัน springfox ของคุณสูงกว่า 2.5, ควรเพิ่ม WebSecurityConfiguration ดังต่อไปนี้:

@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 ที่ถูกต้องตั้งแต่ springfox 2.5+ ทั้งหมดทรัพยากร springfox (ที่กรีดกรายรวม) /swagger-resourcesได้ย้ายไปอยู่ภายใต้ /v2/api-docsเป็นจุดสิ้นสุด api เริ่มต้น (ไม่ต้องกังวลกับ UI) ซึ่งสามารถแทนที่ด้วยตัวแปร config springfox.documentation.swagger.v2.path springfox
Mahieddine M. Ichir

3

ไม่มากก็น้อยหน้านี้มีคำตอบ แต่ทั้งหมดไม่ได้อยู่ที่เดียว ฉันกำลังจัดการกับปัญหาเดียวกันและใช้เวลากับมันค่อนข้างดี ตอนนี้ฉันมีความเข้าใจที่ดีขึ้นแล้วและฉันต้องการแบ่งปันที่นี่:

ฉันเปิดใช้งาน Swagger ui ด้วย Spring websecurity:

หากคุณเปิดใช้งาน Spring Websecurity ตามค่าเริ่มต้นระบบจะบล็อกคำขอทั้งหมดที่ไปยังแอปพลิเคชันของคุณและส่งคืน 401 อย่างไรก็ตามสำหรับ ui ผยองที่จะโหลดในเบราว์เซอร์ swagger-ui.html จะทำการเรียกหลายครั้งเพื่อรวบรวมข้อมูล วิธีที่ดีที่สุดในการดีบักคือเปิด swagger-ui.html ในเบราว์เซอร์ (เช่น google chrome) และใช้ตัวเลือกสำหรับนักพัฒนา (คีย์ 'F12') คุณสามารถดูการโทรหลายครั้งเมื่อโหลดหน้าเว็บและหาก swagger-ui โหลดไม่สมบูรณ์อาจมีบางสายที่ล้มเหลว

คุณอาจต้องบอก Spring websecurity ให้ละเว้นการรับรองความถูกต้องสำหรับรูปแบบเส้นทางที่ผยองหลายรูปแบบ ฉันใช้ swagger-ui 2.9.2 และในกรณีของฉันด้านล่างคือรูปแบบที่ฉันต้องละเลย:

อย่างไรก็ตามหากคุณใช้เวอร์ชันอื่นอาจมีการเปลี่ยนแปลง คุณอาจต้องคิดหาตัวเลือกของนักพัฒนาในเบราว์เซอร์ของคุณตามที่ฉันได้กล่าวไว้ก่อนหน้านี้

@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 การเปิดใช้งาน ui swagger ด้วย interceptor

โดยทั่วไปคุณอาจไม่ต้องการสกัดกั้นคำขอที่ทำโดย swagger-ui.html หากต้องการยกเว้นรูปแบบต่างๆของการกรีดกรายด้านล่างคือรหัส:

รูปแบบเคสส่วนใหญ่สำหรับการรักษาความปลอดภัยของเว็บและตัวสกัดกั้นจะเหมือนกัน

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

}

เนื่องจากคุณอาจต้องเปิดใช้งาน @EnableWebMvc เพื่อเพิ่มตัวดักจับคุณจึงอาจต้องเพิ่มตัวจัดการทรัพยากรเพื่อวางท่าคล้ายกับที่ฉันทำในข้อมูลโค้ดด้านบน


เหตุใดคุณจึงเพิ่ม/csrfการยกเว้น
Vishal

2

จำกัด เฉพาะทรัพยากรที่เกี่ยวข้องกับ Swagger:

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

2

นี่เป็นทางออกที่สมบูรณ์แบบสำหรับการวางท่ากับฤดูใบไม้ผลิการรักษาความปลอดภัย เราอาจต้องการเปิดใช้งาน Swagger ในสภาพแวดล้อมการพัฒนาและ QA ของเราเท่านั้นและปิดใช้งานในสภาพแวดล้อมการผลิต ดังนั้นฉันจึงใช้คุณสมบัติ ( prop.swagger.enabled) เป็นแฟล็กเพื่อข้ามการตรวจสอบความปลอดภัยแบบสปริงสำหรับ swagger-ui ในสภาพแวดล้อม development / 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

ฉันใช้ Spring Boot 5 ฉันมีคอนโทรลเลอร์นี้ที่ฉันต้องการให้ผู้ใช้ที่ไม่ได้รับการพิสูจน์ตัวตนเรียกใช้

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

นี่คือสิ่งที่ฉันทำในการกำหนดค่า

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

หวังว่านี่จะช่วยได้ ....


0

การพิจารณาคำขอ API ทั้งหมดของคุณที่อยู่ในรูปแบบ URL ของ/api/..คุณสามารถบอกให้ spring รักษาความปลอดภัยเฉพาะรูปแบบ URL นี้โดยใช้การกำหนดค่าด้านล่าง ซึ่งหมายความว่าคุณกำลังบอกสปริงว่าจะรักษาความปลอดภัยอะไรแทนที่จะเพิกเฉย

@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
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือระยะสั้นที่ จำกัด คำอธิบายที่เหมาะสมจะช่วยเพิ่มมูลค่าในระยะยาวได้อย่างมากโดยแสดงให้เห็นว่าเหตุใดจึงเป็นวิธีแก้ปัญหาที่ดีและจะทำให้มีประโยชน์มากขึ้นสำหรับผู้อ่านในอนาคตที่มีคำถามอื่น ๆ ที่คล้ายคลึงกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงสมมติฐานที่คุณตั้งขึ้น
Toby Speight
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.