spring boot集成swagger2
raywei 2023-01-29
# 版本 && 依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
copy2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# swagger配置类
package com.raywei.hospital.framework.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.raywei.hospital.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Hospital-Easy")
.description("医院API")
.version("1.0")
.build();
}
@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/");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
copy2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# spring security -- oauth2 设置
package com.raywei.hospital.framework.security.oauth2;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
* 资源服务器配置
*
* @PreAuthorize("hasAuthority('MS_ADMIN')")
*/
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
/**
* 资源认证,在这里配置需要验证账号密码之后才能访问的资源
*
* @param http
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
// 表单认证
http.httpBasic();
// 认证就可以访问
http.authorizeRequests()
// .antMatchers("/**/**").permitAll(); // 允许不登陆即可访问所有的资源
.antMatchers("oauth/**", "/login/**", "/logout/**").permitAll()
.antMatchers("/js/**", "/css/**", "/img/**").permitAll()
// swagger
.antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources/**", "/v2/**").permitAll()
.anyRequest().authenticated();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
copy2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# spring security -- web 设置
package com.raywei.hospital.framework.security;
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.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;
/**
* Security安全配置
* https://www.jianshu.com/p/5f78a11259cb
* https://www.10qianwan.com/articledetail/471343.html
* https://blog.csdn.net/niuxingfan123/article/details/104061585
* https://blog.csdn.net/qq_39089301/article/details/89313968
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private HospitalUserDetailsService hospitalUserDetailsService;
@Autowired
private AuthenticationProvider loginValidateAuthenticationProvider;
/**
* 安全规则拦截
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf的保护
/* 原因:
Spring Security会对POST、PUT、PATCH等数据提交类的请求进行CSRF验证(防止跨站请求伪造攻击),
Spring Security要求这些请求必须携带CSRFToken,但是目前Postman并不会利用Authorization页签中填上的Basic Auth相关信息生成CSRFToken。
你得用自己的登录接口来生成,并将生成的CSRFToken添加到Postman后续的各个测试请求的Headers中(X-CSRFToken)。
https://www.cnblogs.com/xuruiming/p/13296312.html
为了测试方便,这里不使用登录接口拿CSRFToken,而是暂时将Spring Security的CSRF验证关掉即可(交付测试和上生产时记得重新打开)
*/
http.csrf().disable().cors();
// 设置请求安全规则
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll() // 预请求 直接访问 不需要认证
.antMatchers("/oauth/**", "/login/**", "/logout/**").permitAll() // 符合 pattern 的路径可以直接访问 不需要认证
.antMatchers("/js/**", "/css/**", "/img/**").permitAll()
// swagger
.antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources/**", "/v2/**").permitAll()
.anyRequest().authenticated(); // 其他路径的请求 需要认证
// 登录
http.httpBasic();
// 过滤链
// http.addFilterBefore(secUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
// http.addFilterAt(secUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
/**
* 认证
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(hospitalUserDetailsService).passwordEncoder(passwordEncoder());
auth.authenticationProvider(loginValidateAuthenticationProvider);
}
/**
* 注意重写 把AuthenticationManager 注入容器
*
* @return
* @throws Exception
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 密码加密器, 使用spring security需要配置, 加密的方式需要自己new 然后传入
*
* @return
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordMd5SaltEncoder();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
copy2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
参考:
https://www.cnblogs.com/yichunguo/p/12665857.html
https://juejin.cn/post/6844904078942666759
https://blog.csdn.net/China_TomCat/article/details/114214187