Swagger权限认证上:基于Apache Shiro

熵桥蝉翼
• 阅读 3246

有很多文章提到,在生产环境中需要关闭Swagger功能,防止系统资源泄露。今天,我结合自己开发过程中的经验,分享一个只需几行代码便可实现让Apache Shiro接管Swagger认证和授权的方法。如果还有更好的方法,欢迎在文章末尾给我留言,一起交流。

初识Swagger

简单来说,Swagger是一个开放源代码的框架,旨在使用通用化的语言,让开发者和非开发者都能理解你设计的API是什么结构,有什么用途。API文档好比建筑蓝图,在建造房子时,必须按照蓝图的规格参数进行。

通常,一个软件项目会伴随着很多的API文档需要编写,当软件版本变更时,还需要修改所有的API文档细节(例如:请求地址,请求参数,返回值等等)。这是一件极具挑战性的工作。长期以来,工程师们一直在努力寻找一种标准化的流程/方法来解决API文档的设计,编写,测试和维护问题,Swagger就是在这样一种背景下诞生的。
Swagger权限认证上:基于Apache Shiro

Swagger为API文档的设计,开发,测试,维护提供了统一的解决方案。这极大的减轻了开发人员的工作负担。但随之而来的一个问题也会让人担心,通过Swagger UI提供统一的API文档阅览和测试,这会导致在生产环境下暴露系统资源。

我们并不希望所有人都可以查阅系统的API文档,就像不是所有人都有权限查看建筑蓝图一样。那么如何解决这一问题呢?

Apache Shiro接管Swagger权限认证

Swagger官方提供了6种认证和授权方式:basic-authenticationAPI密钥bearer-authenticationOauth 2.0OpenID Connect DiscoveryCookie。但这几种方式在体验上效果都不好(当然,你也可以选择在生产环境中关闭Swagger的功能)。能不能有一种方式,让系统本身的权限认证体系接管Swagger的授权认证工作,让Swagger专注于自己擅长的领域呢?这就是本文要介绍的重点。

快速认识Apache Shiro

Apache Shiro™是一个功能强大且易于使用的Java安全框架,用于执行身份认证,授权,加密和会话管理。你可以轻松地将其集成到你的项目中,且不需要改动太多的代码。Shiro支持一个或多个可插拔的数据源,例如LDAP、JDBC、Active Directory等等,与此同时,Shiro还支持不同粒度的访问控制,如基于用户组,用户角色,资源权限等。
Swagger权限认证上:基于Apache Shiro

使用Shiro接管Swagger认证授权

首先,假定你已经在自己的项目中使用了Swagger,并且你的项目是基于Spring Boot 2.0进行构建的,同时使用Maven对项目的依赖进行管理。如果你的项目还未使用Swagger,请将下面代码配置到pom.xml文件中:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

另外,请检查项目中是否加入了Shiro项目依赖,如果还未添加,请将下面代码配置到pom.xml文件中:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.4.2</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>
备注

shiro-core:Apache Shiro核心依赖包

shiro-ehcache:基于Ehcache实现的数据缓存依赖包

shiro-spring:Apache Shiro与Spring整合依赖包
Swagger权限认证上:基于Apache Shiro

配置Swagger

依赖就绪后,创建一个Swagger的配置文件并设置Swagger要扫描的包路径(通常是Controller所在的包),API文档标题(title),描述(description),版本号(version),联系方式(contact)以及证书名称(license)等等。下面是Swagger配置文件示例:

SwaggerConfiguration.java

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.ramostear.controller"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(
                        new ApiInfoBuilder()
                        .title("Apache Shiro & Swagger")
                        .description("使用Apache Shiro接管Swagger认证和授权")
                        .version("1.0.0")
                        .contact(
                                new Contact("树下魅狐",
                                        "https://www.ramostear.com",
                                        "ramostear@163.com")
                        )
                        .license("The Apache License")
                        .build()
                );
    }
}
注意

除了使用@Configuration对配置类进行注解外,别将@EnableSwagger注解遗漏!

在Shiro中配置Swagger

如果你的项目已经使用Apache Shiro进行认证和授权工作,那么只需要在ShiroFilterFactoryBean的配置代码中加入对Swagger的过滤操作即可。你可以参照下面的代码进行配置:

ShiroConfiguration.java

@Configuration
public class ShiroConfiguration{
    
    @Bean
    public EhCacheManager ehCacheManager(){...}
    
    @Bean
    public CustomShiroRealm customShiroRealm(){...}
    
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setCacheManager(ehCacheManager());
        securityManager.setRealm(customShiroRealm());
        return securityManager;
    }
    ...
    
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> filterChainDefinition = new LinkedHashMap<>();
        ...
            
        filterChainDefinition.put("/swagger-ui.html","authc");
        filterChainDefinition.put("/v2/**","authc");
        filterChainDefinition.put("/swagger-resources/**","authc");
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinition);
        return filterFactoryBean;     
    }
    ....
}
补充

除了上述给出的配置方式外,你可以根据实际需要,配置更细粒度的权限,例如用户组,角色以及资源权限等等。

至此,如果你的项目原本使用了Apache Shiro框架,那么只需在原代码的基础上,增加三行配置代码,即可让Apache Shiro接管Swagger的认证和授权工作。

最后,通过实际项目来演示Apache Shiro接管Swagger认证和授权工作的效果:

Swagger权限认证上:基于Apache Shiro

说明

/admin/swagger请求页面嵌入了一个iframe,其地址为:/swagger-ui.html。具体代码如下:

swagger.html

<html>
    <head>
        ...
    </head>
    <body>
        ...
        <iframe src="./swagger-ui.html" frameborder="0" scrolling="auto"></iframe>
        ...
    </body>
</html>    

当用户登录成功后,可以正常访问Swagger的API文档页面,当注销当前用户后,再次访问Swagger页面,系统会跳转到用户登录页面,要求验证用户身份。


Swagger权限认证上:基于Apache Shiro

点赞
收藏
评论区
推荐文章
Easter79 Easter79
4年前
springboot集成swagger2多模块中文配置详细步骤,解决集成mybatis或mybatis
springboot集成swagger2多模块中文配置详细步骤,解决集成mybatis或mybatisplus无法正常使用问题参考文章:(1)springboot集成swagger2多模块中文配置详细步骤,解决集成mybatis或mybatisplus无法正常使用问题(https://www.oschina.net/action/Go
Easter79 Easter79
4年前
swagger
如果项目已经集成了swagger,只需要在pom.xml添加,如果你的项目没有集成swagger,自行百度或看最下方的链接swaggerbootstrapui是Swagger的前端UI实现,目的是替换Swagger默认的UI实现SwaggerUI,使文档更友好一点儿....swaggerbootstrapui 只是Swagger的UI实现,
Wesley13 Wesley13
4年前
java 后台返回文件流到浏览器
packagecom.springbootblog.controller;importio.swagger.annotations.ApiImplicitParam;importio.swagger.annotations.ApiImplicitParams;importio.swagger.annotations.ApiOperation;
Easter79 Easter79
4年前
Swagger生成的接口需要权限验证的处理方法
通常开发API的时候需要对接口进行权限验证,而我们在使用Swagger生成接口文档界面的时候,直接调用需要权限验证的接口会提示"当前用户没有登陆"!(https://oscimg.oschina.net/oscnet/b70cf279698211b11cb1c2530d42b4958c3.jpg)为了解决此问题,我们需要更改一下Swagger的配
Stella981 Stella981
4年前
Spring MVC 整合 Swagger
Swagger简要说明   将Swagger和SwaggerUI集成到系统中,可以实现接口可视化界面操作。版本号SwaggerUI2.2.10高于该版本,可能会出现“Nooperationsdefinedinspec”错误下载地址:https://github.c
Stella981 Stella981
4年前
SpringBoot整合Swagger3生成接口文档
  前后端分离的项目,接口文档的存在十分重要。与手动编写接口文档不同,swagger是一个自动生成接口文档的工具,在需求不断变更的环境下,手动编写文档的效率实在太低。与新版的swagger3相比swagger2配置更少,使用更加方便。一、pom文件中引入Swagger3依赖<dependency
Stella981 Stella981
4年前
Shiro 放行Swagger
一、前言在使用SpringBootShiroMybatisSwagger开发后台权限管理系统的时候,由于SpringBoot采用了Shiro框架,同时API接口文档使用的Swagger,遇到一个问题,在SpringBoot集成Shiro后,访问Swagger接口需要登陆才可以,由于在项目成型之前需要做接口测试,所以这里记录下如何在Shi
Easter79 Easter79
4年前
Swagger从入门到精通
如何编写基于OpenAPI规范的API文档\TOC\前言编写目的本文介绍如何使用Swagger编写API文档。通过阅读本文,你可以:了解swagger是什么掌握使用swagger编写API文档的基本方法涉及范围本文包括对swagger
Wesley13 Wesley13
4年前
Java Swagger的注释类是怎么被调用到的
比如我有一个Swagger2的Java类,里面有一个方法createRestApi,这个方法加了@Bean的注解,负责生成Swagger文档。!在这里插入图片描述(https://oscimg.oschina.net/oscnet/up5af57bfeacc3a353672efb18bff6312d.png)那么Spring框架是如何知道
Easter79 Easter79
4年前
SpringBoot整合Swagger3生成接口文档
  前后端分离的项目,接口文档的存在十分重要。与手动编写接口文档不同,swagger是一个自动生成接口文档的工具,在需求不断变更的环境下,手动编写文档的效率实在太低。与新版的swagger3相比swagger2配置更少,使用更加方便。一、pom文件中引入Swagger3依赖<dependency
Easter79 Easter79
4年前
SpringCloud中多个子模块如何集成Swagger文档
不知道大家工作中有没有使用Swagger,可能没有用过,但是肯定或多或少的接触过、听说过,它是一款基于Restfull接口的文档在线生成功能测试的工具。网上有很多SpringBoot如何集成Swagger的教程,但是对于微服务而言,多个模块之前应该如何使用Swagger呢?总不能每个模块单独集成一个,那么当有很多个模块的时候,是