swagger与oauth的集成使用

1.Swagger定义

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
个人觉得,swagger的一个最大的优点是能实时同步api与文档。在项目开发过程中,发生过多次:修改代码但是没有更新文档,前端还是按照老旧的文档进行开发,在联调过程中才发现问题的情况(当然依据开闭原则,对接口的修改是不允许的,但是在项目不稳定阶段,这种情况很难避免)。
作用:

  1. 接口的文档在线自动生成。
  2. 功能测试。

2.示例

2.1 引入依赖

<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>2.7.0</version>
</dependency>
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>2.7.0</version>
</dependency>
 <dependency>
	<groupId>com.joinbright.f1</groupId>
	<artifactId>f1-component</artifactId>
 	<version>3.2.0-SNAPSHOT</version>
</dependency>

第一个是API获取的包,第二是官方给出的一个ui界面。

2.2 SwaggerConfigure

@Configuration
@EnableSwagger2
public class SwaggerConfigure implements Serializable {
        // 2.针对授权认证
        //    security.userOauth.clientId
        @Value("${security.userOauth.clientId}")
        private String authClientId;

        //    security.userOauth.clientSecret
        @Value("${security.userOauth.clientSecret}")
        private String authClientSecret;

        @Value("${security.userOauth.type}")
        private String type;

        //    security.userOauth.authorizationUrl
        @Value("${security.userOauth.authorizationUrl}")
        private String authorizationUrl;

        //    security.userOauth.tokenUrl
        @Value("${security.userOauth.tokenUrl}")
        private String tokenUrl;

        @Value("${security.userOauth.tokenName}")
        private String tokenName;

        @Value("${security.userOauth.scope.code}")
        private String scopeCode;

        @Value("${security.userOauth.scope.desc}")
        private String scopeDesc;

        @Value("${app.key}")
        private String appKey;

        @Value("${app.name}")
        private String appName;

        @Value("${app.desc}")
        private String appDesc;

        @Value("${app.version}")
        private String appVersion;

        @Value("${app.termsOfServiceUrl}")
        private String termsOfServiceUrl;

        @Value("${app.contact.name}")
        private String contactName;


        /**
         * Api分组,可以定义多个组
         */
        @Bean
        public Docket jackApi() {
            return new Docket(DocumentationType.SWAGGER_2).groupName("jack")
                    .genericModelSubstitutes(DeferredResult.class)
                    .useDefaultResponseMessages(false)
                    .forCodeGeneration(true)
                    .pathMapping("/")
                    .select()
                    //                .apis(RequestHandlerSelectors.basePackage("net.jack.lt"))
                    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    .paths(PathSelectors.any())
                    .build()
                    .securitySchemes(newArrayList(oauth()))
                    .securityContexts(newArrayList(securityContext()))
                    .apiInfo(apiInfo());
        }

        private ApiInfo apiInfo() {
            ApiInfo apiInfo = new ApiInfoBuilder()
                    .title(appName)
                    .description(appDesc)
                    .termsOfServiceUrl(termsOfServiceUrl)
                    .contact(contactName)
                    .version(appVersion)
                    .build();
            return apiInfo;
        }
        
        @Bean
        SecurityScheme apiKey() {
            return new ApiKey(appName, appKey, "header");
        }

        @Bean
        SecurityContext securityContext() {
            AuthorizationScope[] scopes = new AuthorizationScope[]{new AuthorizationScope(scopeCode, scopeDesc)};
            SecurityReference securityReference = SecurityReference
                    .builder()
                    .reference(type)
                    .scopes(scopes)
                    .build();

            return SecurityContext
                    .builder()
                    .securityReferences(newArrayList(securityReference))
                    .forPaths(PathSelectors.any())//ant("/api/**") // 最好是能够统一前缀
                    .build();
        }

        @Bean
        SecurityScheme oauth() {
            return new OAuthBuilder()
                    .name(type)
                    .grantTypes(grantTypes())
                    .scopes(scopes())
                    .build();
        }

        List<AuthorizationScope> scopes() {
            return newArrayList(new AuthorizationScope(scopeCode, scopeDesc));
        }

        List<GrantType> grantTypes() {
            List<GrantType> grants = newArrayList(new AuthorizationCodeGrant(
                    new TokenRequestEndpoint(authorizationUrl, authClientId, authClientSecret),
                    new TokenEndpoint(tokenUrl, tokenName)));
            return grants;
        }

        @Bean
        public SecurityConfiguration securityInfo() {
            return new SecurityConfiguration(authClientId, authClientSecret, scopeCode, 
                    appKey, appKey, ApiKeyVehicle.HEADER, "", ",");
        }
}

基础的配置是对整个API文档的描述以及一些全局性的配置,对所有接口起作用。这里涉及到两个注解:   
@Configuration是表示这是一个配置类,是JDK自带的注解,前面的文章中也已做过说明。   
@EnableSwagger2的作用是启用Swagger2相关功能。 在这个配置类里面我么实例化了一个Docket对象,这个对象主要包括三个方面的信息:    
 (1)整个API的描述信息,即ApiInfo对象包括的信息,这部分信息会在页面上展示。
 (2)指定生成API文档的包名。     
 (3)指定生成API的路径。按路径生成API可支持四种模式,这个可以参考其源码:

2.3 WebMvcConfig

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

   /**
     * 将Swagger2 的swagger-ui.html加入资源路径下,否则Swagger2静态页面不能访问。要想使资源能够访问,可以有两种方法
     * 一:需要配置类继承WebMvcConfigurationSupport 类,实现addResourceHandlers方法。
     *      但是实现了WebMvcConfigurationSupport以后,Spring Boot的 WebMvc自动配置就会失效,具体表现比如访问不到
     *      静态资源(js,css等)了,这是因为WebMvc的自动配置都在WebMvcAutoConfiguration类中,但是类中有这个注解
     *      @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}),意思是一旦在容器中检测到
     *      WebMvcConfigurationSupport这个类,WebMvcAutoConfiguration类中的配置都不生效。
     *      所以一旦我们自己写的配置类继承了WebMvcConfigurationSupport,相当于容器中已经有了WebMvcConfigurationSupport,
     *      所有默认配置都不会生效,都得自己在配置文件中配置。
     * 二:继承WebMvcConfigurer接口,这里采用此方法 网上有人说使用该方法会导致date编译等问题,可能在配置文件中得到解决,
     *      本人没有碰到,不多做解释
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

2.4 ResourceServerConfiguration

@Configuration
@EnableResourceServer
@Order(100)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers(StaticParams.SWAGGERUI.getSwaggerResource()).permitAll()
                .anyRequest().authenticated();
        // 设置通用的session创建策略
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
    }


    @Bean
    public TokenStore tokenStore() {
        return new RedisTokenStore(connectionFactory);
    }

}

2.5 StaticParams

    public class StaticParams {
    public static class USERROLE {
        public static final String ROLE_ADMIN = "ROLE_ADMIN";
        public static final String ROLE_USER = "ROLE_USER";
        public static final String ROLE_SUPER = "ROLE_SUPER";
    }

    public static class PATHREGX {

        private final static String getPathRex(String path) {
            return "/" + path + "/**";
        }

        public static final String ALL = getPathRex(PATH.ALL);
        public static final String VIEW = getPathRex(PATH.VIEW);
        public static final String ADMIN = getPathRex(PATH.ADMIN);
        public static final String API = getPathRex(PATH.API);
        public static final String RESOURCE = getPathRex(PATH.RESOURCE);
        public static final String STATIC = getPathRex(PATH.STATIC);
        public static final String JS = getPathRex(PATH.JS);
        public static final String CSS = getPathRex(PATH.CSS);
        public static final String IMG = getPathRex(PATH.IMG);
    }

    public static class PATH {
        public static final String ALL = "**";
        public static final String VIEW = "view";
        public static final String ADMIN = "admin";
        public static final String API = "api";
        public static final String RESOURCE = "resource";
        public static final String STATIC = "static";
        public static final String JS = "js";
        public static final String CSS = "css";
        public static final String IMG = "img";
        public static final String WEBSOCKET_SERVICE = "websocket-service";
        public static final String WEBSOCKET = "websocket";
    }

    /**
     * 
     * @Package: com.jb.auth.sso<br>
     * @ClassName: SWAGGERUI<br>
     * @Description: swagger限制地址<br>
     */
    public static class SWAGGERUI {
        public static final String MAIN = "/**/swagger-ui.html";
        public static final String RESOURCES = "/**/swagger-resources/**";
        public static final String API_DOCS = "/**/api-docs";
        public static final String STATIC_RESOURCES = "/**/webjars/springfox-swagger-ui/**";
        /**
         * 
         * @Title: getSwaggerResource
         * @Description: 获取swagger对应ui资源
         * @return
         */
        public static String[] getSwaggerResource() {
            return new String[] { MAIN, RESOURCES, API_DOCS, STATIC_RESOURCES};
        }
    }

}

2.6 API接口

   @ApiOperation("基于分页查询计算点")
    @ApiImplicitParams({
       @ApiImplicitParam(name = "page", value = "页码", paramType = "query", required = true, dataType = "Integer"),
        @ApiImplicitParam(name = "size", value = "条数", paramType = "query", required = true, dataType = "Integer")
    })
    @RequestMapping(path = "/_all/_page", method = RequestMethod.GET)
    @ResponseStatus(code = HttpStatus.OK)
    public InvokeResult<Page<Rule>> findRuleByQueryPage(@RequestParam("page") Integer page,
    @RequestParam("size")Integer size) {
        CheckUtil.CheckPageIndexAndSizeAsException(page,size);

        Page<Rule> ruleCriteria = service.findRuleCriteria(page,size);
        return  InvokeResultUtil.ofSuccessful(ruleCriteria);
    }

@ApiOperation() 用于方法;表示一个http请求的操作 value用于方法描述 notes用于提示内容 tags可以重新分组(视情况而用)

@ApiModel: 用于类,表示对类进行说明,用于参数用实体类接收;
@ApiModelProperty()用于方法,字段; 表示对model属性的说明或者数据操作更改
value–字段说明
name–重写属性名字
dataType–重写属性类型
required–是否必填
example–举例说明 hidden–隐藏

@ApiImplicitParams:用在方法上包含一组参数说明
@ApiImplicitParam: 用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
paramType:参数放在哪个地方
header 请求参数的获取:@RequestHeader
query 请求参数的获取:@RequestParam
path(用于restful接口)请求参数的获取:@PathVariabl
body(不常用)
form(不常用)
name:参数名
dataType:参数类型
required:参数是否必须传
value:参数的意思
defaultValue:参数的默认值

2.7 application.yaml配置

security:
  userOauth:
    clientId: f1autoauth
    clientSecret: f1autoauthsecret
    type: oauth2
    authorizationUrl: http://192.168.1.23:9080/uaa/oauth/authorize
    tokenUrl: http://192.168.1.23:9080/uaa/oauth/token
    tokenName: access_token
    scope:
      code: write
      desc: write
app:
  key: swagger
  name: Stark平台在线API
  desc: 详情http://192.168.1.173/F1-IoT/stark
  version: 1.0.0
  termsOfServiceUrl: http://192.168.1.173/F1-IoT/stark
  contact:
    name: 大数据组

2.8 swagger测试接口
在Chrome浏览器中输入地址:http://ip:port/swagger-ui.html,即可打开swagger-ui界面测试接口。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个快速开发框架,Swagger是一个API文档生成工具,OAuth2是一个授权框架,可以用于保护API。 下面是Spring Boot集成SwaggerOAuth2的代码实现和原理解释: 1. 添加Swagger依赖 在pom.xml中添加Swagger依赖: ```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> ``` 2. 添加Swagger配置 在Spring Boot的配置类中添加Swagger配置: ```java @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } } ``` 3. 添加OAuth2依赖 在pom.xml中添加OAuth2依赖: ```xml <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.1.4.RELEASE</version> </dependency> ``` 4. 添加OAuth2配置 在Spring Boot的配置类中添加OAuth2配置: ```java @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated(); } } ``` 5. 添加Token鉴权 添加Token鉴权的方式是在控制器方法上添加@PreAuthorize注解,指定需要的角色或权限: ```java @RestController @RequestMapping("/api") public class ApiController { @GetMapping("/hello") @PreAuthorize("hasRole('ADMIN')") public String hello() { return "Hello World!"; } } ``` 6. 请求Token 使用OAuth2的客户端工具请求Token: ```java public class OAuth2Client { public static void main(String[] args) { Base64.Encoder encoder = Base64.getEncoder(); String clientCredentials = "client_id:client_secret"; String encodedClientCredentials = encoder.encodeToString(clientCredentials.getBytes()); String url = "http://localhost:8080/oauth/token"; HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.add("Authorization", "Basic " + encodedClientCredentials); MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("grant_type", "client_credentials"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class); System.out.println(response.getBody()); } } ``` 以上就是Spring Boot集成SwaggerOAuth2的代码实现和原理解释。其中Swagger用于生成API文档,OAuth2用于保护API,Token鉴权用于限制访问API的角色或权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值