Swagger整合Jwt授权配置

欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章http://www.javaman.cn/sb2/swagger-jwt

一、Swagger入门

1、什么是Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,它有着如下的优点:

1)及时性 (接口变更后,能够及时准确地通知相关前后端开发人员)

2)规范性 (并且保证接口的规范性,如接口的地址,请求方式,参数及响应格式和错误信息)

3)一致性 (接口信息一致,不会出现因开发人员拿到的文档版本不一致,而出现分歧)

4)可测性 (直接在接口文档上进行测试,以方便理解业务)

2、Swagger生成文档

1)添加pom.xml依赖

  1. <!--swagger-->
  2. <dependency>
  3. <groupId>io.springfox</groupId>
  4. <artifactId>springfox-swagger2</artifactId>
  5. <version>2.7.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>io.springfox</groupId>
  9. <artifactId>springfox-swagger-ui</artifactId>
  10. <version>2.7.0</version>
  11. </dependency>

2)创建swagger配置文件

  1. @Configuration
  2. @EnableSwagger2
  3. public class Swagger2Config {
  4. @Bean
  5. public Docket apiConfig() {
  6. //创建基于Swagger2的配置文件
  7. return new Docket(DocumentationType.SWAGGER_2)
  8. // 调用apiInfo方法,创建一个ApiInfo实例,里面是展示在文档页面信息内容
  9. .apiInfo(apiInfo());
  10. }
  11. private ApiInfo apiInfo() {
  12. return new ApiInfoBuilder()
  13. //标题
  14. .title("接口文档")
  15. //描述
  16. .description("接口文档")
  17. //版本
  18. .version("1.0")
  19. //作者信息
  20. .contact(new Contact("java大师", "http://localhost:8081", "xxx@qq.com"))
  21. .build();
  22. }
  23. }

3)启动程序

访问路径:http://localhost:8081/swagger-ui.html ,出现生成的文档页面。

此为原生界面,很难看,所以我们需要引入swagger-bootstrap-ui,也就是Knife4j的前身

4)使用Knife4j

a)添加pom.xml依赖

  1. <dependency>
  2. <groupId>com.github.xiaoymin</groupId>
  3. <artifactId>knife4j-spring-boot-starter</artifactId>
  4. <version>2.0.7</version>
  5. </dependency>

b)开启Swagger2配置

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. @Configuration
  4. @EnableSwagger2
  5. public class Swagger2Config {
  6. @Bean
  7. public Docket createRestApi() {
  8. return new Docket(DocumentationType.SWAGGER_2)
  9. .pathMapping("/")
  10. .apiInfo(apiInfo())
  11. .select()
  12. //swagger要扫描的包路径
  13. .apis(RequestHandlerSelectors.basePackage("com.dsblog.server.controller"))
  14. .paths(PathSelectors.any())
  15. .build()
  16. }
  17. private ApiInfo apiInfo() {
  18. return new ApiInfoBuilder().title("dsblog接口文档")
  19. .contact(new Contact("java大师","http://localhost:8081/doc.html","fry000@qq.com"))
  20. .version("1.0").description("dsblog接口文档").build();
  21. }

b)重启服务

访问地址:http://localhost:8081/doc.html,这个ui界面看起来就更美观,更符合国人的使用习惯

二、Swagger整合Jwt

1、添加pom.xml依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>com.dsblog</groupId>
  7. <artifactId>dsblog</artifactId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. </parent>
  10. <groupId>com.dsblog</groupId>
  11. <artifactId>dsblog-server</artifactId>
  12. <version>0.0.1-SNAPSHOT</version>
  13. <properties>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. <maven.compiler.source>1.8</maven.compiler.source>
  16. <maven.compiler.target>1.8</maven.compiler.target>
  17. </properties>
  18. <dependencies>
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter-web</artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.projectlombok</groupId>
  25. <artifactId>lombok</artifactId>
  26. <optional>true</optional>
  27. </dependency>
  28. <dependency>
  29. <groupId>mysql</groupId>
  30. <artifactId>mysql-connector-java</artifactId>
  31. <scope>runtime</scope>
  32. </dependency>
  33. <dependency>
  34. <groupId>com.baomidou</groupId>
  35. <artifactId>mybatis-plus-boot-starter</artifactId>
  36. <version>3.4.0</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.freemarker</groupId>
  40. <artifactId>freemarker</artifactId>
  41. <version>2.3.31</version>
  42. </dependency>
  43. <dependency>
  44. <groupId>com.baomidou</groupId>
  45. <artifactId>mybatis-plus-generator</artifactId>
  46. <version>3.3.2</version>
  47. </dependency>
  48. <dependency>
  49. <groupId>io.swagger</groupId>
  50. <artifactId>swagger-annotations</artifactId>
  51. <version>1.5.20</version>
  52. </dependency>
  53. <!--swagger-->
  54. <dependency>
  55. <groupId>io.springfox</groupId>
  56. <artifactId>springfox-swagger2</artifactId>
  57. <version>2.7.0</version>
  58. </dependency>
  59. <dependency>
  60. <groupId>io.springfox</groupId>
  61. <artifactId>springfox-swagger-ui</artifactId>
  62. <version>2.7.0</version>
  63. </dependency>
  64. <dependency>
  65. <groupId>com.github.xiaoymin</groupId>
  66. <artifactId>knife4j-spring-boot-starter</artifactId>
  67. <version>2.0.7</version>
  68. </dependency>
  69. <dependency>
  70. <groupId>org.springframework.boot</groupId>
  71. <artifactId>spring-boot-starter-security</artifactId>
  72. <version>2.3.6.RELEASE</version>
  73. </dependency>
  74. <dependency>
  75. <groupId>io.jsonwebtoken</groupId>
  76. <artifactId>jjwt</artifactId>
  77. <version>0.9.1</version>
  78. </dependency>
  79. </dependencies>
  80. </project>

2、创建Swagger2Config配置文件

  1. package com.dsblog.server.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import springfox.documentation.builders.ApiInfoBuilder;
  5. import springfox.documentation.builders.PathSelectors;
  6. import springfox.documentation.builders.RequestHandlerSelectors;
  7. import springfox.documentation.service.*;
  8. import springfox.documentation.spi.DocumentationType;
  9. import springfox.documentation.spi.service.contexts.SecurityContext;
  10. import springfox.documentation.spring.web.plugins.Docket;
  11. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. @Configuration
  15. @EnableSwagger2
  16. public class Swagger2Config {
  17. @Bean
  18. public Docket createRestApi() {
  19. return new Docket(DocumentationType.SWAGGER_2)
  20. .pathMapping("/")
  21. .apiInfo(apiInfo())
  22. .select()
  23. //swagger要扫描的包路径
  24. .apis(RequestHandlerSelectors.basePackage("com.dsblog.server.controller"))
  25. .paths(PathSelectors.any())
  26. .build()
  27. .securityContexts(securityContexts())
  28. .securitySchemes(securitySchemes());
  29. }
  30. private ApiInfo apiInfo() {
  31. return new ApiInfoBuilder().title("dsblog接口文档")
  32. .contact(new Contact("java大师","http://localhost:8081/doc.html","fry000@qq.com"))
  33. .version("1.0").description("dsblog接口文档").build();
  34. }
  35. private List<SecurityContext> securityContexts() {
  36. //设置需要登录认证的路径
  37. List<SecurityContext> result = new ArrayList<>();
  38. result.add(getContextByPath("/.*"));
  39. return result;
  40. }
  41. //通过pathRegex获取SecurityContext对象
  42. private SecurityContext getContextByPath(String pathRegex) {
  43. return SecurityContext.builder()
  44. .securityReferences(defaultAuth())
  45. .forPaths(PathSelectors.regex(pathRegex))
  46. .build();
  47. }
  48. //默认为全局的SecurityReference对象
  49. private List<SecurityReference> defaultAuth() {
  50. List<SecurityReference> result = new ArrayList<>();
  51. AuthorizationScope authorizationScope = new AuthorizationScope("global",
  52. "accessEverything");
  53. AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
  54. authorizationScopes[0] = authorizationScope;
  55. result.add(new SecurityReference("Authorization", authorizationScopes));
  56. return result;
  57. }
  58. private List<ApiKey> securitySchemes() {
  59. //设置请求头信息
  60. List<ApiKey> result = new ArrayList<>();
  61. ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
  62. result.add(apiKey);
  63. return result;
  64. }
  65. }

3、创建SecurityConfig配置文件

  1. package com.dsblog.server.config.security;
  2. import com.dsblog.server.model.User;
  3. import com.dsblog.server.service.IUserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  8. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  9. import org.springframework.security.config.annotation.web.builders.WebSecurity;
  10. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  11. import org.springframework.security.config.http.SessionCreationPolicy;
  12. import org.springframework.security.core.userdetails.UserDetailsService;
  13. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  14. import org.springframework.security.crypto.password.PasswordEncoder;
  15. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  16. @Configuration
  17. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  18. @Autowired
  19. private IUserService userService;
  20. @Autowired
  21. private RestAuthorizationEntryPoint restAuthorizationEntryPoint;
  22. @Autowired
  23. private RestAccessDeniedHandler restAccessDeniedHandler;
  24. @Override
  25. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  26. auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
  27. }
  28. //主要的配置文件,antMatchers匹配的路径,全部忽略,不进行JwtToken的认证
  29. @Override
  30. public void configure(WebSecurity web) throws Exception {
  31. web.ignoring().antMatchers(
  32. "/login",
  33. "/logout",
  34. "/css/**",
  35. "/js/**",
  36. "/index.html",
  37. "favicon.ico",
  38. "/doc.html",
  39. "/webjars/**",
  40. "/swagger-resources/**",
  41. "/v2/api-docs/**"
  42. );
  43. }
  44. @Override
  45. protected void configure(HttpSecurity http) throws Exception {
  46. http.csrf().disable()
  47. .sessionManagement()
  48. .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  49. .and()
  50. .authorizeRequests()
  51. .anyRequest().authenticated()
  52. .and()
  53. .headers()
  54. .cacheControl();
  55. //添加Jwt登录授权拦截器
  56. http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
  57. //添加未登录和未授权结果返回
  58. http.exceptionHandling()
  59. .accessDeniedHandler(restAccessDeniedHandler)
  60. .authenticationEntryPoint(restAuthorizationEntryPoint);
  61. }
  62. @Override
  63. @Bean
  64. public UserDetailsService userDetailsService(){
  65. return username -> {
  66. User user = userService.getUserByUsername(username);
  67. if(null!=user){
  68. return user;
  69. }
  70. return null;
  71. };
  72. }
  73. @Bean
  74. public PasswordEncoder passwordEncoder(){
  75. return new BCryptPasswordEncoder();
  76. }
  77. @Bean
  78. public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
  79. return new JwtAuthenticationTokenFilter();
  80. }
  81. }

4、创建测试Controller,其中/login登录和/logout退出方法不需要Authorize验证,和上面的重写方法configure(WebSecurity web)匹配,user/info方法需要Authorize验证才能进行访问

  1. package com.dsblog.server.controller;
  2. import com.dsblog.server.model.ResultBean;
  3. import com.dsblog.server.model.User;
  4. import com.dsblog.server.model.UserLoginParam;
  5. import com.dsblog.server.service.IUserService;
  6. import io.swagger.annotations.Api;
  7. import io.swagger.annotations.ApiOperation;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. import org.springframework.web.bind.annotation.RequestBody;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import javax.servlet.http.HttpServletRequest;
  14. import java.security.Principal;
  15. @Api(tags = "LoginController")
  16. @RestController
  17. public class LoginController {
  18. @Autowired
  19. private IUserService userService;
  20. @ApiOperation("登录")
  21. @PostMapping("/login")
  22. public ResultBean login(@RequestBody UserLoginParam userLoginParam, HttpServletRequest request){
  23. return userService.login(userLoginParam.getUsername(),userLoginParam.getPassword(),request);
  24. }
  25. @ApiOperation("退出")
  26. @PostMapping("/logout")
  27. public ResultBean logout(){
  28. return ResultBean.success("退出成功!");
  29. }
  30. @ApiOperation("获取当前登录用户")
  31. @GetMapping("/user/info")
  32. public User getUserInfo(Principal principal){
  33. if(null == principal){
  34. return null;
  35. }
  36. String username = principal.getName();
  37. User user = userService.getUserByUsername(username);
  38. user.setPassword(null);
  39. return user;
  40. }
  41. }

5、重启程序,输入http://localhost:8081/doc.html

6、测试

1)首先调用/user/info,会看到提示未登录,请先登录。需要登录授权才能够进行方法的测试

2)接着调用登录请求,输入用户名和密码获取JwtToken

3)获取token后,监测网络,发现会将Authorization放入请求头部发送到后台

4)Authorize加入Bearer和JwtToken

5)携带token发送到后台获取用户信息,验证通过

Swagger整合Jwt授权配置的更多相关文章

  1. swagger api文档添加jwt授权配置

    最近写的swagger文档,要加jwt授权,所以几经google终于搞定了,简简单单几行配置如下: securityDefinitions: APIKey: type: apiKey name: Au ...

  2. 【SpringBoot技术专题】「JWT技术专区」SpringSecurity整合JWT授权和认证实现

    JWT基本概念 JWT,即 JSON Web Tokens(RFC 7519),是一个广泛用于验证 REST APIs 的标准.虽说是一个新兴技术,但它却得以迅速流行. JWT的验证过程是: 前端(客 ...

  3. 学习ASP.NET Core(05)-使用Swagger与Jwt授权

    上一篇我们使用IOC容器解决了依赖问题,同时简单配置了WebApi环境,本章我们使用一下Swagger,并通过Jwt完成授权 一.Swagger的使用 1.什么是Swagger 前后端分离项目中,后端 ...

  4. 【SpringBoot技术专题】「权限校验专区」Shiro整合JWT授权和认证实现

    本章介绍一下常用的认证框架Shiro结合springboot以及集合jwt快速带您开发完成一个认证框架机制. Maven配置依赖 <dependency> <groupId>o ...

  5. 如何使用Swagger为.NET Core 3.0应用添加JWT授权说明文档

    简介 本教程采用WHY-WHAT-HOW黄金圈思维模式编写,黄金圈法则强调的是从WHY为什么学,到WHAT学到什么,再到HOW如何学.从模糊到清晰的学习模式.大家的时间都很宝贵,我们做事前先想清楚为什 ...

  6. Spring Boot初识(4)- Spring Boot整合JWT

    一.本文介绍 上篇文章讲到Spring Boot整合Swagger的时候其实我就在思考关于接口安全的问题了,在这篇文章了我整合了JWT用来保证接口的安全性.我会先简单介绍一下JWT然后在上篇文章的基础 ...

  7. swagger的说明、配置及使用

    一.What is swagger? 官方介绍:Swagger是一个规范且完整的框架,提供描述.生产.消费和可视化RESTful Web Service.专业角度:Swagger是由庞大工具集合支撑的 ...

  8. Spring Security整合JWT,实现单点登录,So Easy~!

    前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...

  9. net Core3.1 Swagger加JWT权限

    1.Swagger中开启JWT服务 #region swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new ...

随机推荐

  1. Lesson10——NumPy 迭代数组

    NumPy 教程目录 NumPy 迭代数组 NumPy 迭代器对象  numpy.nditer  提供了一种灵活访问一个或者多个数组元素的方式. 迭代器最基本的任务的可以完成对数组元素的访问. Exa ...

  2. notepad++颜色属性解释

    Global Styles Indent guideline style  缩进参考线的颜色Brace highlight style 鼠标指针在框架左右时框架的颜色(如css中{}   js中的() ...

  3. 如何通过opensea-js获取OpenSea的数据

    OpenSea作为NFT最大的交易平台,随着NFT的火热之后,热度也是出现翻天覆地的变化.作为开发人员肯定好奇有没有可以与opensea交互的包来开发相关的工具或者快速获取opensea的数据.别急, ...

  4. 帆软报表(finereport)单元格函数,OP参数

    单元格模型:单元格数据和引用:数据类型.实际值与显示值.单元格支持的操作单元格样式:行高列宽.隐藏行列.自动换行.上下标.文字竖排.大文本字段分页时断开.标识说明.格式刷单元格Web属性:web显示. ...

  5. 《PHP程序员面试笔试宝典》——什么是职场暗语?

    本文摘自<PHP程序员面试笔试宝典> 文末有该书电子版下载. 随着求职大势的变迁发展,以往常规的面试套路因为过于单调.简明,已经被众多"面试达人"们挖掘出了各种&quo ...

  6. 用 Beep 函数让主板“唱”《生日歌》

    用 Beep 函数,让你的主板也会"唱歌".Beep 可以通过控制主板扬声器的发声频率和节拍来演奏美妙的旋律.本文就通过C#演示,调用Beep函数,演奏生日快乐歌.首先我们来看下 ...

  7. Redis 源码简洁剖析 15 - AOF

    AOF 是什么 AOF 持久化的实现 命令追加 AOF 文件的写入和同步 AOF 文件的载入和数据还原 AOF 重写 为什么需要重写 什么是重写 如何重写 AOF 后台重写 为什么需要后台重写 带来的 ...

  8. GitLab API使用小结

    GitLab API使用小结 背景描述 需求描述: 最近因为工作上的需求,需要对GitLab进行大批量的操作,又因为服务器不在境内,所以所有的操作都需要连接VPN来进行FQ访问.目前大概有6000多个 ...

  9. JVM学习——内存空间(学习过程)

    JVM--内存空间 关于内存的内容,内存的划分.JVM1.7 -> 1.8的变化比较大 JVM指令执行的时候,是基于栈的操作.每一个方法执行的时候,都会有一个属于自己的栈帧的数据结构.栈的深度, ...

  10. Java NIO Selector 的使用

    之前的文章已经把 Java 中 NIO 的 Buffer.Channel 讲解完了,不太了解的可以先回过头去看看.这篇文章我们就来聊聊 Selector -- 选择器. 首先 Selector 是用来 ...