Cách cấu hình Spring Security để cho phép truy cập URL Swagger mà không cần xác thực


92

Dự án của tôi có Spring Security. Sự cố chính: Không thể truy cập URL swagger tại http: // localhost: 8080 / api / v2 / api-docs . Nó thông báo Thiếu hoặc tiêu đề Ủy quyền không hợp lệ.

Ảnh chụp màn hình cửa sổ trình duyệt pom.xml của tôi có các mục sau

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

các mục nhập 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);
    }
}

Câu trả lời:


176

Thêm điều này vào lớp WebSecurityConfiguration của bạn sẽ thực hiện thủ thuật.

@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
Nếu bạn sử dụng swagger-ui, bạn cần một cái gì đó như sau: .antMatchers ("/ v2 / api-docs", "/ configuration / ui", "/ swagger-resources", "/ configuration / security", "/ swagger-ui .html "," / webjars / ** "," / swagger-resources / configuration / ui "," / swagger-ui.html "). allowAll ()
Daniel Martín

2
Trong trường hợp của tôi, quy tắc này đang hoạt động: .antMatchers ("/ v2 / api-docs", "/ configuration / ui", "/ swagger-resources", "/ configuration / security", "/swagger-ui.html", "/ webjars / **", "/ swagger-resources / configuration / ui", "/ swattery‌ r-ui.html", "/ swagger-resources / configuration / security"). allowAll ()
nikolai.serdiuk

6
Cần thêm quy tắc: .antMatchers ("/", "/ csrf", "/ v2 / api-docs", "/ swagger-resources / configuration / ui", "/ configuration / ui", "/ swagger-resources", "/ swagger-resources / configuration / security", "/ configuration / security", "/swagger-ui.html", "/ webjars / **"). allowAll ()
Mate Šimović

5
Cảm ơn vì câu trả lời! Có rủi ro bảo mật nào khi cho phép truy cập webjars / ** không?
ssimm

câu trả lời rất hữu ích
Praveenkumar Beedanal

26

Tôi đã cập nhật bằng / configuration / ** và / swagger-resources / ** và nó hoạt động với tôi.

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

}

Hoàn hảo! Đã giải quyết vấn đề.
Madhu

24

Tôi đã gặp sự cố tương tự khi sử dụng Spring Boot 2.0.0.M7 + Spring Security + Springfox 2.8.0. Và tôi đã giải quyết vấn đề bằng cách sử dụng cấu hình bảo mật sau đây cho phép truy cập công khai vào tài nguyên giao diện người dùng 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
sau khi thêm lớp này, tôi có thể nhìn thấy vênh vang-ui nhưng API không được truy cập thông qua người đưa thư ngay cả với access_token, việc tiếp cận cấm lỗi như dưới đây,{ "timestamp": 1519798917075, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/<some path>/shop" }
Chandrakant Audhutwar

@ChandrakantAudhutwar xóa antMatchers("/**").authenticated()tuyên bố hoặc thay thế bằng cấu hình xác thực của riêng bạn. Hãy cẩn thận, bạn biết rõ hơn mình đang làm gì với bảo mật.
naXa 28/02/18

vâng, nó đã hoạt động. Tôi đã nghĩ đến việc chỉ bỏ qua swagger-ui, nhưng các API khác vì nó được bảo mật. bây giờ các API của tôi cũng bị bỏ qua.
Chandrakant Audhutwar

@ChandrakantAudhutwar bạn không cần phải copy-paste cả SecurityConfigurationlớp vào dự án của mình. Bạn nên có riêng SecurityConfigurationnơi bạn cho phép yêu cầu tài nguyên giao diện người dùng Swagger và giữ an toàn cho các API của bạn.
naXa

Tôi đã AuthorizationServerConfigurerAdaptertriển khai lớp giúp xác thực API.
Chandrakant Audhutwar

13

Đối với những người sử dụng phiên bản swagger 3 mới hơn 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
Lưu ý: Nếu điều này ngăn bạn nhận được lỗi "Yêu cầu xác thực" nhưng chỉ hiển thị cho bạn một trang trống, tôi cũng phải thêm "/ swagger-resources / **" và "/ swagger-resources" vào danh sách đó và nó đã được khắc phục nó cho tôi.
Vinícius M

5

nếu phiên bản springfox của bạn cao hơn 2,5 , nên thêm WebSecurityConfiguration như sau:

@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 nói đúng, kể từ springfox 2.5+, tất cả các tài nguyên của Springfox (bao gồm swagger) đã được chuyển xuống dưới /swagger-resources. /v2/api-docslà thiết bị đầu cuối vênh vang mặc định api (không có mối quan tâm với giao diện người dùng), có thể được ghi đè với biến cấu hình springfox.documentation.swagger.v2.path springfox
Mahieddine M. Ichir

3

Ít nhiều trang này có câu trả lời nhưng tất cả đều không ở một nơi. Tôi đã giải quyết cùng một vấn đề và đã dành thời gian khá thoải mái cho nó. Bây giờ tôi đã hiểu rõ hơn và tôi muốn chia sẻ nó ở đây:

Tôi Bật Swagger ui với bảo mật web Spring:

Nếu bạn đã bật Spring Websecurity theo mặc định, nó sẽ chặn tất cả các yêu cầu đến ứng dụng của bạn và trả về 401. Tuy nhiên, để tải swagger ui trong trình duyệt swagger-ui.html thực hiện một số lệnh gọi để thu thập dữ liệu. Cách tốt nhất để gỡ lỗi là mở swagger-ui.html trong trình duyệt (như google chrome) và sử dụng tùy chọn nhà phát triển (phím 'F12'). Bạn có thể thấy một số lệnh gọi được thực hiện khi trang tải và nếu swagger-ui không tải hoàn toàn, có thể một số trong số chúng đang bị lỗi.

bạn có thể cần phải yêu cầu bảo mật web Spring bỏ qua xác thực đối với một số mẫu đường dẫn vênh nhau. Tôi đang sử dụng swagger-ui 2.9.2 và trong trường hợp của tôi, dưới đây là các mẫu mà tôi phải bỏ qua:

Tuy nhiên, nếu bạn đang sử dụng một phiên bản khác, phiên bản của bạn có thể thay đổi. bạn có thể phải tìm ra tùy chọn của mình với tùy chọn nhà phát triển trong trình duyệt của bạn như tôi đã nói trước đây.

@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 Cho phép ui vênh vang với thiết bị đánh chặn

Nói chung, bạn có thể không muốn chặn các yêu cầu được thực hiện bởi swagger-ui.html. Để loại trừ một số kiểu vênh nhau dưới đây là mã:

Hầu hết các trường hợp mẫu cho bảo mật web và bộ chặn sẽ giống nhau.

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

}

Vì bạn có thể phải bật @EnableWebMvc để thêm trình chặn, bạn cũng có thể phải thêm trình xử lý tài nguyên để vênh vang tương tự như tôi đã làm trong đoạn mã trên.


Tại sao bạn lại thêm /csrfvào loại trừ?
Vishal

2

Chỉ giới hạn đối với các tài nguyên liên quan đến Swagger:

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

2

Đây là một giải pháp hoàn chỉnh cho Swagger với Spring Security . Chúng tôi có thể chỉ muốn kích hoạt Swagger trong môi trường phát triển và QA của chúng tôi và vô hiệu hóa nó trong môi trường sản xuất. Vì vậy, tôi đang sử dụng thuộc tính ( prop.swagger.enabled) làm cờ để bỏ qua xác thực bảo mật mùa xuân cho swagger-ui chỉ trong môi trường phát triển / 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

Tôi đang sử dụng Spring Boot 5. Tôi có bộ điều khiển này mà tôi muốn một người dùng chưa được xác thực gọi.

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

Đây là những gì tôi đã làm trong cấu hình.

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

Hi vọng điêu nay co ich....


0

Xem xét tất cả các yêu cầu API của /api/..bạn có mẫu url của bạn, bạn có thể yêu cầu mùa xuân chỉ bảo mật mẫu url này bằng cách sử dụng cấu hình bên dưới. Có nghĩa là bạn đang nói với mùa xuân những gì cần bảo mật thay vì những gì cần bỏ qua.

@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
Cảm ơn bạn vì đoạn mã này, đoạn mã có thể cung cấp một số trợ giúp ngắn hạn có giới hạn. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ khiến nó hữu ích hơn cho những người đọc trong tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm cả những giả định bạn đã đưa ra.
Toby Speight
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.