Swagger2集成JWT登陆步骤,结合Spring拦截器自定义需要登陆的URL

Swagger用过的都知道是在线文档神器,配置步骤也十分简单,但是网上和Spring整合没有结合Spring拦截器一起使用的,今天笔者来抛砖引玉,分享下Swagger整合JWT过程中结合Spring拦截器的使用,有什么不对的地方还请大家指正。

1、pom.xml添加swagger2依赖,目前最新版本的是2.9.2:

			<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>

2、新增登陆拦截器,JWT网上有很多实现:

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //从header中取出jwt
        String token = request.getHeader("X-Auth-Token");
        //...此处省略token验证的过程
        return true;
    }
}

3、 配置拦截器:
因为swagger也需要用到这些排除的白名单URL,所以白名单URL是放在application.properties这个配置文件的:

weshop-wechat.login-interceptor-exclude-path[0]=/
weshop-wechat.login-interceptor-exclude-path[1]=/csrf
weshop-wechat.login-interceptor-exclude-path[2]=/error
weshop-wechat.login-interceptor-exclude-path[3]=/favicon.ico
weshop-wechat.login-interceptor-exclude-path[4]=/swagger-resources/**
weshop-wechat.login-interceptor-exclude-path[5]=/webjars/**
weshop-wechat.login-interceptor-exclude-path[6]=/v2/**
weshop-wechat.login-interceptor-exclude-path[7]=/swagger-ui.html/**
# 前面几条是固定不需要登录拦截,否则访问Swagger就需要登录了
weshop-wechat.login-interceptor-exclude-path[8]=/wechat/brand/**
weshop-wechat.login-interceptor-exclude-path[9]=/wechat/catalog/**
weshop-wechat.login-interceptor-exclude-path[10]=/wechat/goods/**
weshop-wechat.login-interceptor-exclude-path[11]=/wechat/home/**
weshop-wechat.login-interceptor-exclude-path[12]=/wechat/search/**
weshop-wechat.login-interceptor-exclude-path[13]=/wechat/topic/**
weshop-wechat.login-interceptor-exclude-path[14]=/wechat/auth/login
weshop-wechat.login-interceptor-exclude-path[15]=/wechat/dev/{userId}/token

配置文件类,方便获取白名单的URL数组集合

@ConfigurationProperties(prefix = "weshop-wechat")
public class WeshopWechatProperties {

    private List<String> loginInterceptorExcludePath;

    public List<String> getLoginInterceptorExcludePath() {
        return loginInterceptorExcludePath;
    }
    public void setLoginInterceptorExcludePath(List<String> loginInterceptorExcludePath) {
        this.loginInterceptorExcludePath = loginInterceptorExcludePath;
    }
}

拦截器配置的config类

@Configuration
@EnableConfigurationProperties(WeshopWechatProperties.class)
public class WebConfig implements WebMvcConfigurer {
	//配置文件类
    private final WeshopWechatProperties weshopWechatProperties;
   //获取配置的构造方法
    public WechatWebConfig(WeshopWechatProperties weshopWechatProperties) {
        this.weshopWechatProperties = weshopWechatProperties;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")//拦截所有的路径
                .excludePathPatterns(weshopWechatProperties.getLoginInterceptorExcludePath().toArray(new String[]{}));//白名单URL
    }
}

4、配置Swagger2,这一步是关键:

@Configuration
@EnableSwagger2 //这个注解一定不能忘记加,否则swagger就不生效,也可以加在启动类上面
@EnableConfigurationProperties(WeshopWechatProperties.class)
public class Swagger2Config {
	//这里同样需要用到配置的白名单URL
    private WeshopWechatProperties weshopWechatProperties;

    public Swagger2Config(WeshopWechatProperties weshopWechatProperties) {
        this.weshopWechatProperties = weshopWechatProperties;
    }

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("tech.wetech.weshop.wechat.controller"))// 指定api路径
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("微信小程序端接口文档")
                .description("WESHOP | 又一个小程序商城应用")
                .termsOfServiceUrl("https://github.com/cjbi")
                .version("1.0")
                .build();
    }

    private List<ApiKey> securitySchemes() {
    	//参数1:字段的名字,参数2:字段的键,参数3:参数位置
        return Arrays.asList(new ApiKey("Auth-Token", "Auth-Token", "header"));
    }
	
	//认证的上下文,这里面需要指定哪些接口需要认证
    private List<SecurityContext> securityContexts() {
        SecurityContextBuilder builder = SecurityContext.builder().securityReferences(securityReferences());
        //指定需要认证的path,大写的注意,这里就用到了配置文件里面的URL,需要自己实现path选择的逻辑
        builder.forPaths(forExcludeAntPaths(weshopWechatProperties.getLoginInterceptorExcludePath()));
        return Arrays.asList(builder.build());
    }

    /**
     * 匹配登陆拦截器过滤地址
     * @param antPatterns - ant Patterns
     * @return predicate that matches a particular ant pattern
     */
    private Predicate<String> forExcludeAntPaths(final List<String> antPatterns) {
        return (input) -> {
        	//使用spring的ant路径配置
            AntPathMatcher matcher = new AntPathMatcher();
            //如果不是白名单的URL,就需要认证
            return !antPatterns.stream().anyMatch(antPattern -> matcher.match(antPattern, input));
        };
    }
	
	//这个方法是验证的作用域,不能漏了
    private List<SecurityReference> securityReferences() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        return Arrays.asList(
                new SecurityReference("Access-Token", new AuthorizationScope[]{authorizationScope}));
    }

}

5、代码部分都完成了,来看看最终效果:
这个是登陆窗口,右上角Anthorize按钮可以设置全局Token
在这里插入图片描述

需要登陆的接口右边有个小锁,可以设置单个接口的token,没有小锁的就是不需要登陆的白名单接口,是从配置文件读取的
在这里插入图片描述
至此,swagger针对Spring拦截器的认证就完成了,欢迎评论给我留言。

原创文章 45 获赞 151 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u010697681/article/details/95963814