⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_34125999/article/details/107579972/ 「你携秋月揽星河丶」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1 概述

SpringCloud Gateway Security oauth2.0 搭建微服务统一认证授权。

项目概述:

  • common:公用代码,实体、工具类等等…
  • gateway:网关
  • uaa:用户登录认证服务
  • school:微服务

环境概述:

  • SpringBoot 版本:2.3.1.RELEASE
  • SpringCloud版本:Hoxton.SR6
  • SpringCloudAlibaba:2.2.1.RELEASE
  • MybatisPlus:3.3.2

技能要求:

需要掌握SpringCloud 、SpringCloudAlibaba 基础使用,了解RBAC、OAuth2.0、JWT。

2 父工程

父工程pom依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.rosh</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>gateway</module>
<module>uaa</module>
<module>school</module>
<module>common</module>
</modules>
<packaging>pom</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencyManagement>
<dependencies>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

3 uaa认证服务搭建

3.1 pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>com.rosh</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>uaa</artifactId>

<dependencies>
<!--springboot && spring cloud-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--授权-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!--数据库-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.rosh</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>

3.2 application.yml

server:
port: 8500

spring:
application:
name: uaa-server
cloud:
nacos:
discovery:
server-addr: 192.168.226.39:8848
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver

mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
global-config:
db-config:
id-type: auto

#暴露监控
management:
endpoints:
web:
exposure:
include: '*'

3.3 Security核心配置

(1) TokenConfig

@Configuration
public class TokenConfig {

/**
* 秘钥串
*/
private static final String SIGNING_KEY = "uaa";


@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}

/**
* 配置令牌管理
*/
@Bean
public AuthorizationServerTokenServices tokenService(ClientDetailsService clientDetailsService,TokenStore tokenStore
,JwtAccessTokenConverter accessTokenConverter) {
DefaultTokenServices service = new DefaultTokenServices();
service.setClientDetailsService(clientDetailsService);
service.setSupportRefreshToken(true);
service.setTokenStore(tokenStore);
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Collections.singletonList(accessTokenConverter));
service.setTokenEnhancer(tokenEnhancerChain);
return service;
}

/**
* 授权码存储方式
*/

@Bean
public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {
return new JdbcAuthorizationCodeServices(dataSource);
}

}

(2) AuthorizationServer

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {


@Autowired
private AuthorizationCodeServices authorizationCodeServices;

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private AuthorizationServerTokenServices tokenService;

@Autowired
@Qualifier("myClientDetailsService")
private ClientDetailsService clientService;

/**
* 配置客户端详细信息服务
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

clients.withClientDetails(clientService);
}

@Bean("myClientDetailsService")
public ClientDetailsService clientDetailsService(DataSource dataSource, PasswordEncoder passwordEncoder) {
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setPasswordEncoder(passwordEncoder);
return clientDetailsService;
}


/**
* 令牌访问端点
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager)
.authorizationCodeServices(authorizationCodeServices)
.tokenServices(tokenService)
.allowedTokenEndpointRequestMethods(HttpMethod.POST)
.exceptionTranslator(new WebResponseTranslator());

}

/**
* 令牌访问端点安全策略
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()")
.allowFormAuthenticationForClients();
}

}

(3) WebSecurityConfig

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired
private SuccessHandler successHandler;

@Autowired
private FailureHandler failureHandler;

@Autowired
private LogoutHandler logoutHandler;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}


@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().formLogin()
.loginProcessingUrl("/login").permitAll()
.successHandler(successHandler).permitAll()
.failureHandler(failureHandler).permitAll().and()
.logout().logoutSuccessHandler(logoutHandler).and()
.authorizeRequests()
.antMatchers("/**").permitAll();
}
}

(4) SecurityUserDetailService

@Service
@Slf4j
public class SecurityUserDetailService implements UserDetailsService {


@Autowired
private UserService userService;

@Autowired
private PermissionService permissionService;


@Override
public UserDetails loadUserByUsername(String username) {

UserEntity user = userService.getUserByUsername(username);
if (user == null) {
return null;
}
//获取权限
List<PermissionEntry> permissions = permissionService.getPermissionsByUserId(user.getId());
List<String> codes = permissions.stream().map(PermissionEntry::getCode).collect(Collectors.toList());
String[] authorities = null;
if (CollectionUtils.isNotEmpty(codes)) {
authorities = new String[codes.size()];
codes.toArray(authorities);
}
//身份令牌
String principal = JSON.toJSONString(user);
return User.withUsername(principal).password(user.getPassword()).authorities(authorities).build();
}
}

3.4 启动类

@EnableDiscoveryClient
@SpringBootApplication
public class UaaApplication {

public static void main(String[] args) {
SpringApplication.run(UaaApplication.class);
}
}

4 Gateway服务搭建

4.1 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>com.rosh</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--授权-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!--fegin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.rosh</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>

4.2 application.yml

server:
port: 9000

spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 192.168.226.39:8848
gateway:
routes:
- id: school-server
uri: lb://school-server
predicates:
- Path=/api/school/**
filters:
- RewritePath=/api/school/(?<segment>.*),/$\{segment}
- id: uaa-server
uri: lb://uaa-server
predicates:
- Path=/api/uaa/**
filters:
- RewritePath=/api/uaa/(?<segment>.*),/$\{segment}

4.3 Security配置

(1) TokenConfig

@Configuration
public class TokenConfig {

/**
* 秘钥串
*/
private static final String SIGNING_KEY = "uaa";


@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}


}

(2) SecurityConfig

@EnableWebFluxSecurity
@Configuration
public class SecurityConfig {


@Bean
public SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) {
return http.authorizeExchange()
.pathMatchers("/**").permitAll()
.anyExchange().authenticated()
.and().csrf().disable().build();
}
}

4.4 过滤器(核心)

@Component
@Slf4j
public class GatewayFilterConfig implements GlobalFilter, Ordered {


@Autowired
private TokenStore tokenStore;


@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String requestUrl = exchange.getRequest().getPath().value();
AntPathMatcher pathMatcher = new AntPathMatcher();
//1 uaa服务所有放行
if (pathMatcher.match("/api/uaa/**", requestUrl)) {
return chain.filter(exchange);
}
//2 检查token是否存在
String token = getToken(exchange);
if (StringUtils.isBlank(token)) {
return noTokenMono(exchange);
}
//3 判断是否是有效的token
OAuth2AccessToken oAuth2AccessToken;
try {
oAuth2AccessToken = tokenStore.readAccessToken(token);
Map<String, Object> additionalInformation = oAuth2AccessToken.getAdditionalInformation();
//取出用户身份信息
String principal = MapUtils.getString(additionalInformation, "user_name");
//获取用户权限
List<String> authorities = (List<String>) additionalInformation.get("authorities");
JSONObject jsonObject=new JSONObject();
jsonObject.put("principal",principal);
jsonObject.put("authorities",authorities);
//给header里面添加值
String base64 = EncryptUtil.encodeUTF8StringBase64(jsonObject.toJSONString());
ServerHttpRequest tokenRequest = exchange.getRequest().mutate().header("json-token", base64).build();
ServerWebExchange build = exchange.mutate().request(tokenRequest).build();
return chain.filter(build);
} catch (InvalidTokenException e) {
log.info("无效的token: {}", token);
return invalidTokenMono(exchange);
}



}


/**
* 获取token
*/
private String getToken(ServerWebExchange exchange) {
String tokenStr = exchange.getRequest().getHeaders().getFirst("Authorization");
if (StringUtils.isBlank(tokenStr)) {
return null;
}
String token = tokenStr.split(" ")[1];
if (StringUtils.isBlank(token)) {
return null;
}
return token;
}


/**
* 无效的token
*/
private Mono<Void> invalidTokenMono(ServerWebExchange exchange) {
JSONObject json = new JSONObject();
json.put("status", HttpStatus.UNAUTHORIZED.value());
json.put("data", "无效的token");
return buildReturnMono(json, exchange);
}

private Mono<Void> noTokenMono(ServerWebExchange exchange) {
JSONObject json = new JSONObject();
json.put("status", HttpStatus.UNAUTHORIZED.value());
json.put("data", "没有token");
return buildReturnMono(json, exchange);
}


private Mono<Void> buildReturnMono(JSONObject json, ServerWebExchange exchange) {
ServerHttpResponse response = exchange.getResponse();
byte[] bits = json.toJSONString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//指定编码,否则在浏览器中会中文乱码
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}


@Override
public int getOrder() {
return 0;
}
}

4.5 跨域配置

@Configuration
public class GatewayCorsConfiguration {

@Bean
public CorsWebFilter corsWebFilter(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}

}

4.6 启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class GatewayApplicaion {

public static void main(String[] args) {
SpringApplication.run(GatewayApplicaion.class);
}

}

5 School微服务

5.1 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>com.rosh</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>school</artifactId>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.rosh</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--授权-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

5.2 application.yml

server:
port: 8000

spring:
application:
name: school-server
cloud:
nacos:
discovery:
server-addr: 192.168.226.39:8848

5.3 security配置

(1) TokenConfig

@Configuration
public class TokenConfig {

private static final String SIGNING_KEY = "uaa";


@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(SIGNING_KEY);
return converter;
}
}

(2) ResouceServerConfig

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResouceServerConfig extends ResourceServerConfigurerAdapter {


@Autowired
private TokenStore tokenStore;

/**
* 资源ID
*/
private static final String RESOURCE_ID = "res1";


/**
* 资源配置
*/
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID)
.tokenStore(tokenStore)
.stateless(true)
.accessDeniedHandler(new CustomAccessDeniedHandler());
}

/**
* 请求配置
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").access("#oauth2.hasScope('ROLE_ADMIN')")
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}


}

5.4 过滤器(核心)

@Component
public class AuthenticationFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("json-token");
if (StringUtils.isNotBlank(token)){
String json = EncryptUtil.decodeUTF8StringBase64(token);
JSONObject jsonObject = JSON.parseObject(json);
//获取用户身份信息、权限信息
String principal = jsonObject.getString("principal");
UserEntity user = JSON.parseObject(principal, UserEntity.class);
JSONArray tempJsonArray = jsonObject.getJSONArray("authorities");
String[] authorities = tempJsonArray.toArray(new String[0]);
//身份信息、权限信息填充到用户身份token对象中
UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user,null,
AuthorityUtils.createAuthorityList(authorities));
//创建details
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//将authenticationToken填充到安全上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
filterChain.doFilter(request,response);
}
}

5.5 Controller

(1) 学生接口

@RestController
@RequestMapping("/student")
public class StudentController {


/**
* 老师权限或学生权限
*/
@GetMapping("/grade")
@PreAuthorize("hasAnyAuthority('teacher','student')")
public Object rs(HttpServletRequest request){
Map<String,Object> map=new HashMap<>();
map.put("张三",100);
return map;
}


}

(2) 老师接口

@RestController
@RequestMapping("/teacher")
public class TeacherController {


/**
* 老师权限
*/
@GetMapping("/math/grade")
@PreAuthorize("hasAuthority('teacher')")
public Object rs() {
List<Map<String, Object>> maps = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Map<String, Object> map = new HashMap<>();
map.put("张三" + i, 100);
maps.add(map);
}
return maps;
}


}

6 集成测试

6.1 账号准备

{"username":"kakaxi","password":"123","authorities":["student","teacher"]}

{"username":"mingren","password":"123","authorities":["student"]}

6.2 启动

6.3 测试

(1) 申请老师权限token

(2) 带着token验证接口

(3) 申请学生token

(4) 验证token

7 Github地址

code、sql脚本

https://github.com/zhurongsheng666/distributed-security

文章目录
  1. 1. 1 概述
  2. 2. 2 父工程
  3. 3. 3 uaa认证服务搭建
    1. 3.0.1. 3.1 pom依赖
    2. 3.0.2. 3.2 application.yml
    3. 3.0.3. 3.3 Security核心配置
    4. 3.0.4. 3.4 启动类
  • 4. 4 Gateway服务搭建
    1. 4.0.1. 4.1 pom
    2. 4.0.2. 4.2 application.yml
    3. 4.0.3. 4.3 Security配置
    4. 4.0.4. 4.4 过滤器(核心)
    5. 4.0.5. 4.5 跨域配置
    6. 4.0.6. 4.6 启动类
  • 5. 5 School微服务
    1. 5.0.1. 5.1 pom
    2. 5.0.2. 5.2 application.yml
    3. 5.0.3. 5.3 security配置
    4. 5.0.4. 5.4 过滤器(核心)
    5. 5.0.5. 5.5 Controller
  • 6. 6 集成测试
    1. 6.0.1. 6.1 账号准备
    2. 6.0.2. 6.2 启动
    3. 6.0.3. 6.3 测试
  • 7. 7 Github地址