There have been many articles about the need to turn off Swagger functionality in production environments to prevent system resource leaks. Today, BASED on my own development experience, I share a method for Apache Shiro to take over Swagger authentication and authorization in just a few lines of code. If there is a better way, welcome to leave a message to me at the end of the article, and communicate with me.

I met Swagger

To put it simply, Swagger is an open source framework designed to use a universal language so that developers and non-developers alike can understand what the structure of your API is and what it does. API documents are like architectural blueprints. When building a house, you must follow the specifications of the blueprints.

Often, a software project comes with a lot of API documentation to write, and when the software version changes, all the API documentation details need to be modified (e.g., request address, request parameters, return values, etc.). It’s a very challenging job. Swagger was born out of a long-standing effort by engineers to find a standardized process/approach to API documentation design, authoring, testing, and maintenance.

Swagger provides a unified solution for API documentation design, development, testing, and maintenance. This greatly lightens the developer’s workload. However, there is also a concern that providing uniform API document viewing and testing through The Swagger UI can lead to exposing system resources in a production environment.

We don’t want everyone to have access to the system’s API documentation, just like not everyone has access to building blueprints. So how to solve this problem?

Apache Shiro takes over Swagger permission authentication

Swagger officially provides six authentication and authorization methods: basic-authentication, API key, Bearer Authentication, Oauth 2.0, OpenID Connect Discovery and Cookie. None of these works well for the experience (of course, you can turn Off Swagger in production). Is there a way to let Swagger focus on what Swagger is good at? This is the focus of this article.

Get to know Apache Shiro quickly

Apache Shiro™ is a powerful and easy-to-use Java security framework for performing authentication, authorization, encryption, and session management. You can easily integrate it into your project without having to change too much code. Shiro supports one or more pluggable data sources, such as LDAP, JDBC, Active Directory, and so on, as well as different granularity of access control based on user groups, user roles, resource permissions, and so on.

Use Shiro to take over Swagger certification authorization

First, assume that you already use Swagger in your project, and that your project is built on Spring Boot 2.0, while using Maven to manage your project’s dependencies. If your project does not already use Swagger, configure the following code into the POM.xml file:

<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>
Copy the code

Also, check whether Shiro project dependencies have been added to the project, and if not, configure the following code into the POM.xml file:

<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>
Copy the code

note

Shiro-core: Apache Shiro core dependency package

Shro-ehcache: Data cache dependency package based on ehcache implementation

Shiro – Spring: Apache Shiro integrates dependencies with Spring

Configuration Swagger

With dependencies in place, create a Configuration file for Swagger and set the package path (usually the package Controller is in), API document title, description, version, Contact information and certificate name. Here is an example Swagger configuration file:

SwaggerConfiguration.java

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

    @Bean
    public Docket createRestApi(a){
        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("Take over Swagger authentication and Authorization with Apache Shiro")
                        .version("1.0.0")
                        .contact(
                                new Contact("The Fox under the Tree."."https://www.ramostear.com"."[email protected]")
                        )
                        .license("The Apache License") .build() ); }}Copy the code

Pay attention to

In addition to using @Configuration to annotate Configuration classes, don’t leave out the @enablesWagger annotation!

Configure Swagger in Shiro

If your project already uses Apache Shiro for authentication and authorization, just add Swagger filtering to the ShiroFilterFactoryBean configuration code. You can use the following code to configure:

ShiroConfiguration.java

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

supplement

In addition to the above configuration, you can configure more fine-grained permissions, such as user groups, roles, and resource permissions, as required.

If your project originally uses the Apache Shiro framework, just add three lines of configuration code and Apache Shiro will take over Swagger’s authentication and authorization.

Finally, we demonstrate the effect of Apache Shiro taking over Swagger certification and authorization through a real project:

instructions

The /admin/swagger request page has an embedded iframe with the address: /swagger-ui.html. The specific code is as follows:

swagger.html

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

If you log in to Swagger successfully, you can access Swagger’s API document page. If you log out of the current user and access Swagger’s API document page again, the system goes to the user login page and asks you to verify the user’s identity.