zoukankan      html  css  js  c++  java
  • spring boot:swagger3的安全配置(swagger 3.0.0 / spring security / spring boot 2.3.3)

    一,swagger有哪些环节需要注意安全?

    1,生产环境中,要关闭swagger

       application.properties中配置:

      springfox.documentation.swagger-ui.enabled=false

    2,swagger使用一台专用的服务器来部署,

       可以访问的ip地址要做限制,

       外部的防火墙和应用中都做限制,

    3,自定义访问swagger的url

     4, 可以访问swagger的用户要做权限的验证

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,演示项目的相关信息

    1,项目地址

    https://github.com/liuhongdi/swagger3security

    2,项目功能说明:

         演示了swagger3的安全配置

    3,项目结构:如图:

    三,配置文件说明

    1,pom.xml

            <!-- swagger3 begin -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>3.0.0</version>
            </dependency>
            <!-- spring security -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>

    2,application.properties

    #error
    server.error.include-stacktrace=always
    #error
    logging.level.org.springframework.web=trace
    #swagger,使可用
    springfox.documentation.swagger-ui.enabled=true
    #改变url
    springfox.documentation.swagger-ui.base-url=/lhddoc
    #设置允许访问的ip地址白名单
    swagger.access.iplist = 192.168.3.1,127.0.0.1

    四,java代码说明

    1,Swagger3Config.java

    @EnableOpenApi
    @Configuration
    public class Swagger3Config implements WebMvcConfigurer {
    
        @Bean
        public Docket createRestApi() {
            //返回文档摘要信息
            return new Docket(DocumentationType.OAS_30)
                    .apiInfo(apiInfo())
                    .select()
                    //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    .apis(RequestHandlerSelectors.withMethodAnnotation(Operation.class))
                    .paths(PathSelectors.any())
                    .build()
                    .globalRequestParameters(getGlobalRequestParameters())
                    .globalResponses(HttpMethod.GET, getGlobalResonseMessage())
                    .globalResponses(HttpMethod.POST, getGlobalResonseMessage());
        }
    
        //生成接口信息,包括标题、联系人等
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("Swagger3接口文档")
                    .description("如有疑问,请联系开发工程师老刘。")
                    .contact(new Contact("刘宏缔", "https://www.cnblogs.com/architectforest/", "371125307@qq.com"))
                    .version("1.0")
                    .build();
        }
    
        //生成全局通用参数
        private List<RequestParameter> getGlobalRequestParameters() {
            List<RequestParameter> parameters = new ArrayList<>();
            parameters.add(new RequestParameterBuilder()
                    .name("appid")
                    .description("平台id")
                    .required(true)
                    .in(ParameterType.QUERY)
                    .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                    .required(false)
                    .build());
            parameters.add(new RequestParameterBuilder()
                    .name("udid")
                    .description("设备的唯一id")
                    .required(true)
                    .in(ParameterType.QUERY)
                    .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                    .required(false)
                    .build());
            parameters.add(new RequestParameterBuilder()
                    .name("version")
                    .description("客户端的版本号")
                    .required(true)
                    .in(ParameterType.QUERY)
                    .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                    .required(false)
                    .build());
             return parameters;
        }
    
        //生成通用响应信息
        private List<Response> getGlobalResonseMessage() {
            List<Response> responseList = new ArrayList<>();
            responseList.add(new ResponseBuilder().code("404").description("找不到资源").build());
             return responseList;
        }
    }

    配置swagger3

    2,HomeController.java

    @Api(tags = "首页信息管理")
    @Controller
    @RequestMapping("/home")
    public class HomeController {
    
        @Operation(summary = "session详情")
        @GetMapping("/session")
        @ResponseBody
        public String session() {
            HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
            Enumeration e   =   session.getAttributeNames();
            String s = "";
            while( e.hasMoreElements())   {
                String sessionName=(String)e.nextElement();
                s += "name="+sessionName+";<br/>";
                s += "value="+session.getAttribute(sessionName)+";";
            }
            return s;
        }
    
    }

    查看当前登录用户的session

    3,SecurityConfig.java

    @Configuration
    @EnableWebSecurity
     public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
         @Value("${swagger.access.iplist}")
         private String iplist;
    
         @Override
         protected void configure(HttpSecurity http) throws Exception {
                     //得到iplist列表
                    String iprule = "";
                    //hasIpAddress('10.0.0.0/16') or hasIpAddress('127.0.0.1/32')
                    String[] splitAddress=iplist.split(",");
                    for(String ip : splitAddress){
                         if (iprule.equals("")) {
                             iprule = "hasIpAddress('"+ip+"')";
                         } else {
                             iprule += " or hasIpAddress('"+ip+"')";
                         }
                    }
                    String swaggerrule = "hasAnyRole('ADMIN','DEV') and ("+iprule+")";
    
                      //login和logout
                      http.formLogin()
                             .defaultSuccessUrl("/home/session")
                            .failureUrl("/login-error.html")
                            .permitAll()
                           .and()
                           .logout();
    
                      //匹配的页面,符合限制才可访问
                      http.authorizeRequests()
                      //.antMatchers("/actuator/**").hasIpAddress("127.0.0.1")
                      //.antMatchers("/admin/**").access("hasRole('admin') and (hasIpAddress('127.0.0.1') or 
    //hasIpAddress('192.168.1.0/24') or hasIpAddress('0:0:0:0:0:0:0:1'))");
    .antMatchers("/lhddoc/**").access(swaggerrule) .antMatchers("/goods/**").hasAnyRole("ADMIN","DEV"); //剩下的页面,允许访问 http.authorizeRequests().anyRequest().permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { //添加两个账号用来做测试 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("lhdadmin") .password(new BCryptPasswordEncoder().encode("123456")) .roles("ADMIN","USER") .and() .withUser("lhduser") .password(new BCryptPasswordEncoder().encode("123456")) .roles("USER"); } }

    spring security的配置,重点是ip地址白名单的限制要加入

    4,Goods.java等,可以从github.com查看

    五,测试效果

    1,无权限的访问效果:

     用lhduser账号登录

    从session页面可以看到当前登录用户的授权角色是:ROLE_USER

     因为没有权限,访问swagger时会报错

    2,有权限访问时的效果:

    用lhdadmin登录

     查看session:

     可以看到用户权限包括:ROLE_ADMIN

    访问swagger:

    http://127.0.0.1:8080/lhddoc/swagger-ui/

    返回:

    3,从非授权的ip地址访问:

    既使用获得授权的用户账号登录也会报错,因为ip未授权

    六,查看spring boot的版本

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.3.RELEASE)
  • 相关阅读:
    .NET开发微信公众号之创建自定义菜单
    FOR XML PATH 可以将查询结果根据行输出成XML格式
    Node入门
    javascript客户端检测技术
    理解OAuth 2.0(转)
    RESTful API 设计指南(转)
    forever让nodejs应用后台执行
    Git使用教程
    NodeJS基础教程
    windows系统下简单nodejs安装及环境配置
  • 原文地址:https://www.cnblogs.com/architectforest/p/13559651.html
Copyright © 2011-2022 走看看