1

之前项目中整合Swagger都是直接通过依赖springfox-swaggerspringfox-swagger-ui两个jar包来实现的,最近发现springfox 3.0.0版本已经有了自己的SpringBoot Starter,使用起来更契合SpringBoot项目,非常方便,推荐给大家!

使用官方Starter

我们先使用官方Starter来整合Swagger看看是否够简单!

  • 首先在pom.xml中添加springfox官方Swagger依赖;

<!--springfox swagger官方Starter-->

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
  • 添加Swagger的Java配置,配置好Api信息和需要生成接口文档的类扫描路径即可;
/**
 * Swagger2API文档的配置
 */
@Configuration
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mybatis.plus"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SwaggerUI演示")
                .description("Spring Boot Swagger2 构建把把智能")
                .contact(new Contact("wlb", null, null))
                .version("1.0")
                .build();
    }
}

注:这里不再需要 @EnableSwagger2注解

swagger

  • 两步即可搞定SpringBoot集成Swagger,是不是很简单!

与之前版本相比

之前我们使用的是springfox 2.9.2版本,接下来对比下3.0.0的SpringBoot Starter使用,看看有何不同!

  • 旧版本需要依赖springfox-swagger2springfox-swagger-ui两个配置,新版本一个Starter就搞定了,而且之前的版本如果不使用新版本的swagger-modelsswagger-annotations依赖,访问接口会出现NumberFormatException问题;
<dependencies>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>
    <!--解决Swagger 2.9.2版本NumberFormatException-->
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.6.0</version>
    </dependency>
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>1.6.0</version>
    </dependency>
</dependencies>
@Configuration
@EnableSwagger2
@Profile(value = {"dev"})
public class Swagger2Config {
    
}
  • 新版本我们在SpringBoot配置文件中进行配置即可,springfox.documentation.enabledapplication-dev.yml配置为true,在application-prod.yml中配置为false。

整合Spring Security使用

我们经常会在项目中使用Spring Security实现登录认证,接下来我们来讲下如何使用Swagger整合Spring Security,实现访问需要登录认证的接口。

  • 如何访问需要登录认证的接口?只需在访问接口时添加一个合法的Authorization请求头即可,下面是Swagger相关配置;
/**
 * Swagger2API文档的配置
 */
@Configuration
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mybatis.plus"))
                .paths(PathSelectors.any())
                .build()
                //添加登录认证
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

     //构建 api文档的详细信息函数
 private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //页面标题
        .title("Spring Boot Swagger2 构建把把智能")
         //条款地址
        .termsOfServiceUrl("http://despairyoke.github.io/")
        .contact(new Contact("wlb", null, null))
        .version("1.0")
        //描述
        .description("API 描述")
        .build();
 }

    private List<SecurityScheme> securitySchemes() {
        //设置请求头信息
        List<SecurityScheme> result = new ArrayList<>();
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
        result.add(apiKey);
        return result;
    }

    private List<SecurityContext> securityContexts() {
        //设置需要登录认证的路径
        List<SecurityContext> result = new ArrayList<>();
        result.add(getContextByPath("/brand/.*"));
        return result;
    }

    private SecurityContext getContextByPath(String pathRegex) {
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex(pathRegex))
                .build();
    }

    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> result = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        result.add(new SecurityReference("Authorization", authorizationScopes));
        return result;
    }
}
  • 我们需要在Spring Security中配置好Swagger静态资源的无授权访问,比如首页访问路径/swagger-ui/
package com.spring.security.demo.config;
import com.spring.security.demo.security.JwtAuthenticationFilter;
import com.spring.security.demo.security.JwtAuthenticationProvider;
import com.spring.security.demo.security.JwtLoginFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
/**
 * 对SpringSecurity的配置的扩展,支持自定义白名单资源路径和查询用户逻辑
 */
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
 private UserDetailsService userDetailsService;
 @Override
 public void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 如果直接定制UserDetailsService ,而不自定义 AuthenticationProvider,可以直接在配置文件 WebSecurityConfig 中这样配置。
 // 指定自定义的获取信息获取服务
//        auth.userDetailsService(userDetailsService);
 // 使用自定义登录身份认证组件----> 指定了自定义身份认证组件 JwtAuthenticationProvider,并注入 UserDetailsService auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService));
 }
    @Override
 protected void configure(HttpSecurity http) throws Exception {
    // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf
    http.cors().and().csrf()
        .disable()
        .sessionManagement()// 基于token,所以不需要session
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问
                "/",
                "/swagger-ui/",
                "/*.html",
                "/favicon.ico",
                "/**/*.html",
                "/**/*.css",
                "/**/*.js",
                "/swagger-resources/**",
                "/v2/api-docs/**"
        )
        .permitAll()
        .antMatchers("/login")// 对登录注册要允许匿名访问
        .permitAll()
       .antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求
        .permitAll()
        .anyRequest()// 除上面外的所有请求全部需要鉴权认证
        .authenticated();
         // 退出登录处理器
         http.logout().logoutSuccessHandler(new             HttpStatusReturningLogoutSuccessHandler());
 // 开启登录认证流程过滤器----> 指定了登录认证流程过滤器 JwtLoginFilter,由它来触发登录认证
//        http.addFilterBefore(new JwtLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
 // 访问控制时登录状态检查过滤器----> 指定了访问控制过滤器 JwtAuthenticationFilter,在授权时解析令牌和设置登录状态
 http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
 }
    //初始化authenticationManager
 @Bean
 @Override public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
 }
}
  • 调用登录接口获取token,账号密码为admin:123456
  • 点击Authorize按钮后输入Authorization请求头,之后就可以访问需要登录认证的接口了。

Authorization

总结

Swagger官方Starter解决了之前整合Swagger的一系列问题,简化了SpringBoot整合Swagger的过程,使用起来更加方便了。同时对于一些复杂的配置使用基本没有变化,一些之前的使用方式依然可以使用!


isWulongbo
228 声望26 粉丝

在人生的头三十年,你培养习惯,后三十年,习惯铸就你