Spring Boot Security - 如果用户未通过 Oauth2 进行身份验证,如何禁用对 swagger ui 页面的端点的访问

Posted

技术标签:

【中文标题】Spring Boot Security - 如果用户未通过 Oauth2 进行身份验证,如何禁用对 swagger ui 页面的端点的访问【英文标题】:Spring Boot Security - How to disable access to endpoints for swagger ui page if the user is not authenticated with Oauth2 【发布时间】:2021-09-21 10:57:02 【问题描述】:

如果用户未通过 Oauth2(swagger ui 页面上的授权按钮)进行身份验证,我正在尝试禁用对 "/v2/api-docs" 端点的访问。

    我的 spring 安全配置如下:

    @配置 @EnableResourceServer 公共类 ResourceServerConfig 扩展 ResourceServerConfigurerAdapter

     @Override
     public void configure(HttpSecurity http) throws Exception 
         http.authorizeRequests().antMatchers("/", "/api/health", "/api/info").permitAll().antMatchers("/api/v1/**").
                 authenticated();
     
    

    以及我配置swagger Oauth2身份验证的这个类

     @Configuration
     @EnableAuthorizationServer
     public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter 
      private static final String USER_INVALID = "User Name or Password is invalid";
     @Autowired
     private AuthenticationManager authenticationManager;
    
     @Autowired
     DataSource dataSource;
    
     @Autowired
     @Qualifier("customUserDetailsService")
     private UserDetailsService userDetailsService;
    
     @Bean
     public PasswordEncoder passwordEncoder() 
         return new BCryptPasswordEncoder();
     
    
     @Override
     public void configure(AuthorizationServerSecurityConfigurer security) throws Exception 
         security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated").allowFormAuthenticationForClients().passwordEncoder(passwordEncoder());
     
    
     @Override
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
         clients.jdbc(dataSource);
     
    
     @Override
     public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
    
         endpoints.tokenStore(new JdbcTokenStore(dataSource)).authenticationManager(this.authenticationManager).userDetailsService(userDetailsService)
                 .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT).exceptionTranslator(ex -> ResponseEntity.status(
                         HttpStatus.UNAUTHORIZED).body(OAuth2Exception.create(OAuth2Exception.UNAUTHORIZED_CLIENT, USER_INVALID))).;
     
    
     @Bean
     public FilterRegistrationBean<CorsFilter> corsFilter() 
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
         CorsConfiguration config = new CorsConfiguration();
         config.setAllowCredentials(true);
         config.addAllowedOrigin("*");
         config.addAllowedHeader("*");
         config.addAllowedMethod("*");
         source.registerCorsConfiguration("/**", config);
         FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(new CorsFilter(source));
         bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
         return bean;
     
    

    在 application.properties 我添加以下属性:

host.full.dns.auth.link=http://oauthserver.example.com:8081
app.client.id=test-client
app.client.secret=clientSecret
auth.server.schem=http

如果用户未通过 Oauth2 进行身份验证,我该如何禁用对 api-docs 的访问?

【问题讨论】:

【参考方案1】:

    swagger-ui.html 调用/v2/api-docs 来填充页面 敏感信息。所以,我覆盖doFilterInternal from OncePerRequestFilter。如果 swagger-ui 调用文档 然后通话将通过。如果用户尝试调用 文档直接它会显示错误的请求。

    @组件 公共类 CustomFilter 扩展 OncePerRequestFilter @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) 抛出 ServletException, IOException 字符串路径 = httpServletRequest.getRequestURI(); 字符串授权 = httpServletRequest.getHeader("Referer"); if ("/v2/api-docs".equals(path) && authorization.isEmpty()) httpServletResponse.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid Locale"); 返回; filterChain.doFilter(httpServletRequest, httpServletResponse);

swagger-ui.html 文件现在是静态资源。并且对于 swagger-ui.html 已经在我的 swagger-ui.html 上受到保护 更改了以下内容:

 <script type="text/javascript">
    $(function () 
      var url = window.location.search.match(/url=([^&]+)/);
      var auth = window.sessionStorage.getItem("Authorization");
      if (url && url.length > 1) 
        url = decodeURIComponent(url[1]);
       else if (auth) 
        url = "/v2/api-docs";
      
// some code
      window.swaggerUi.load();
      swaggerUi.api.clientAuthorizations.add("oauth2schema",new SwaggerClient.ApiKeyAuthorization("Authorization",'Bearer '+auth,"header"));

      function log() 
        if ('console' in window) 
          console.log.apply(console, arguments);
        
      

【讨论】:

以上是关于Spring Boot Security - 如果用户未通过 Oauth2 进行身份验证,如何禁用对 swagger ui 页面的端点的访问的主要内容,如果未能解决你的问题,请参考以下文章

安全框架Spring Boot 整合 Spring Security

Spring Boot Security 基于角色的访问控制

已在Spring Boot / Security注册中验证电子邮件

Spring boot json错误媒体类型和spring security

将 Waffle Spring Security XML 配置迁移到 Spring Boot

在Spring Boot中使用Spring Security实现权限控制