【问题标题】:Restrict Swagger UIs to specific roles将 Swagger UI 限制为特定角色
【发布时间】:2021-04-24 02:15:36
【问题描述】:

我正在尝试将 Swagger 用户界面 (UI) 的访问权限限制为特定角色(例如 Swagger API 用户、系统管理员用户等...)

我在这个 SO 问题中尝试了答案 - Restrict access to Swagger UI

所以我的代码类看起来像

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * XLogger.
     */
    private static final XLogger LOG = XLoggerFactory.getXLogger(WebSecurityConfig.class);

    @Value("${my.property.allowedOrigins}")
    private String[] corsAllowedOrigins;

    @Value("${my.property.excludeUrlPattern}")
    private String[] excludeUrlPattern;

    @Autowired
    ApplicationContext applicationContext;

    /**
     * The AuthenticationSuccessHandler.
     */
    @Autowired
    HSSAuthenticationSuccessHandler authenticationSuccessHandler;

    /**
     * The runtime properties
     */
    @Autowired
    RuntimeProperties runtimeProperties;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOG.entry(http);

        String[] noAuthPermitAllPatterns = runtimeProperties.getApplicationProperties().getNoAuthPermitAllPatterns();

        http.authorizeRequests()
                .antMatchers("/swagger-ui/**", "/**/swagger-ui/**", "/v3/api-docs/**", "/**/v3/api-docs/**")
                .hasRole("ADMIN").antMatchers(noAuthPermitAllPatterns).permitAll().anyRequest().authenticated().and()
                .formLogin().failureHandler(authenticationFailureHandler()).successHandler(authenticationSuccessHandler)
                .loginPage("/saml/login").permitAll().and().logout().logoutSuccessUrl("/logoutSuccess").permitAll()
                .invalidateHttpSession(true).and().csrf().disable().cors()
                .configurationSource(corsConfigurationSource());
        http.addFilterBefore((MetadataGeneratorFilter) applicationContext.getBean("metadataGeneratorFilter"),
                ChannelProcessingFilter.class).addFilterAfter(
                        (FilterChainProxy) applicationContext.getBean("samlFilter"), BasicAuthenticationFilter.class);

        LOG.exit();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        LOG.entry();

        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList(corsAllowedOrigins));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT"));
        configuration.setAllowCredentials(true);
        // the below three lines will add the relevant CORS response headers
        configuration.addAllowedOrigin("*");
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return LOG.exit(source);
    }

    @Override
    @Bean(name = "webAuthenticationManagerBean")
    public AuthenticationManager authenticationManagerBean() throws Exception {
        LOG.entry();
        return LOG.exit(super.authenticationManagerBean());
    }

    /**
     * Authentication Failure Handler
     *
     * @return The Authentication Failure Handler
     */
    @Bean(name = "authenticationFailureHandler")
    protected AuthenticationFailureHandler authenticationFailureHandler() {
        LOG.entry();

        String defaultFailureUrl = runtimeProperties.getApplicationProperties().getDefaultFailureURL();
        ExceptionMappingAuthenticationFailureHandler authFailureHandler = new ExceptionMappingAuthenticationFailureHandler();
        authFailureHandler.setDefaultFailureUrl(defaultFailureUrl);
        Map<String, String> mappings = new HashMap<>();
        mappings.put("org.springframework.security.authentication.InternalAuthenticationServiceException",
                defaultFailureUrl);
        mappings.put("org.springframework.security.saml.SAMLAuthenticationToken", defaultFailureUrl);
        mappings.put("org.springframework.security.authentication.AuthenticationServiceException", defaultFailureUrl);
        authFailureHandler.setExceptionMappings(mappings);

        return LOG.exit(authFailureHandler);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        LOG.entry(web);
        web.ignoring().antMatchers(excludeUrlPattern);
        LOG.exit();
    }
}

这仍然允许我访问 Swagger UI @ http://{localUrl}/swagger-ui/index.html?configUrl=/{localUrl}/v3/api-docs/swagger-config

另外,两种 configure() 方法有什么区别,一种使用HttpSecurity,另一种使用WebSecurity? excludeUrlPattern 确实包含招摇模式,所以我想知道这是否会与我正在尝试做的事情产生冲突。

我想我期待的是 401 Unauthorized 响应。我对 Swagger 完全陌生,因此我们不胜感激!

【问题讨论】:

  • @aksappy 我不认为我想要“修剪 swagger-ui.html 显示的操作”,我想一起限制 UI。
  • 我质疑这种改变的实际用例。 Swagger 页面是您的 API 的文档 - 需要查看 Swagger UI 页面的用户肯定需要检查您的 /login(或等效)端点的定义,以提供包含您希望检查的角色的凭据?为什么 Basic Auth 不够用?

标签: java spring-boot spring-security swagger swagger-ui


【解决方案1】:

与其他端点的方式相同。这仍然会让其他人下载 swagger 配置,如果你真的需要那种级别的控制,你也可以阻止 /api-docs/**

...
  .antMatchers("/swagger-ui/**") // For URI starting with swagger-ui
  .hasRole("USER")
  .antMatchers("/**/swagger-ui/**") // For URI that contains swagger-ui
  .hasRole("USER")
...

【讨论】:

  • 我的端点实际上分解为localhost:{portnumber}/***/********/swagger-ui/index.html?configUrl=/** */********/v3/api-docs/swagger-config 所以我已经尝试了你推荐的,我已经尝试了“/***/******”的模式**/swagger-ui*/**”。这两种方式仍然允许访问 swagger ui。
  • @Shar1er80 我已经更新了答案。 Spring security 查找此处记录的 ant 模式。 docs.spring.io/spring-framework/docs/current/javadoc-api/org/…。 OP中的URL模式是第一次采用。
  • 我已更新我的问题以包含更多源代码。我还添加了您的建议,但仍然可以访问 swagger ui。
  • 您是否在 application.properties 中定义了任何安全配置? swagger url 是唯一有此问题的 URL 吗?我可以在一个小时左右的时间内设置一个演示工作应用程序,以显示它的工作版本。
  • 我正在修改现有代码,所以我不知道设置了什么。查看 application.yaml,我没有看到任何类似于安全设置的内容(例如 Basic Auth、API Keys、Bearer Auth 等)
猜你喜欢
  • 2017-06-09
  • 2011-03-18
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 2021-07-22
相关资源
最近更新 更多