直接进入主题
spring cloud gateway 简介
This project provides a library for building an API Gateway on top of Spring MVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency
springcloud gateway 官方文档 spring.io/projects/sp…
oauth的认证权限可以参考blog.csdn.net/a1583577465… 传送门
常见的网关认证模式
1.网关充当资源服务器 同时转发相关的认证请求到认证服务器 用户请求不同的资源 在网关层验证,判断权限等操作;
2.网关只负责转发操作 进行验证在每个资源服务上
这里采用第二种网关认证方式
源码位置: github.com/passliang/t…
项目整体结构如下
auth-server 作为认证中心
gateway 作为网关 负责转发相关操作 仅仅作为网关
一.首先搭建注册中心
tiger 父工程 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.style</groupId>
<artifactId>tiger</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>tiger</name>
<description>oauth2.0</description>
<modules>
<module>auth-server</module>
<module>gateway</module>
<module>registry</module>
<module>user</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR8</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
注册中心 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.style</groupId>
<artifactId>tiger</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>registry</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>registry</name>
<description>registry</description>
<dependencies>
<!-- eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.yaml 配置
server:
port: 20020
spring:
application:
name: regisry
eureka:
client:
### 取消Eureka服务器自我注册
registerWithEureka: false
### 注册中心的服务器,没有必要再去检索服务
fetchRegistry: false
instance:
hostname: localhost
server:
waitTimeInMsWhenSyncEmpty: 0
#关闭自我保护
enableSelfPreservation: false
#剔除时间间隔,单位:毫秒
evictionIntervalTimerInMs: 4000
3.启动配置文件
@SpringBootApplication
@EnableEurekaServer
public class RegistryApplication {
public static void main(String[] args) {
SpringApplication.run(RegistryApplication.class, args);
}
}
二.网关
使用springcloud的gateway
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.style</groupId>
<artifactId>tiger</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway</artifactId>
<version>1.0.0</version>
<name>gateway</name>
<description>gateway</description>
<dependencies>
<!-- eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- consul-discovery-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!-- actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.yaml配置文件
bootstrap.yaml
server:
port: 20060
spring:
application:
name: gateway
cloud:
zookeeper:
# zookeeper 服务发现与注册失效(默认)
enabled: false
consul:
# consul 服务发现与注册失效(默认)
enabled: false
profiles:
#切换不同 环境 使用zookeeper 或者consul
active: eureka
eureka:
client:
# Eureka 服务发现与注册失效(默认)
enabled: false
--- # Profile For Eureka
spring:
profiles: eureka
eureka:
server: # 官方不存在的配置(自定义配置)
host: 127.0.0.1
port: 20020
client:
service-url:
#注册中心地址
#多注册中心
# defaultZone: http://localhost:20021/eureka,http://localhost:20022/eureka,http://localhost:20023/eureka
defaultZone: http://localhost:20020/eureka
# 5 秒轮训一次
registryFetchIntervalSeconds: 5
enabled: true
instance:
# eureka client发送心跳给server端后,续约到期时间(默认90秒)
leaseExpirationDurationInSeconds: 10
#发送心跳续约间 5秒 发一次 心跳
leaseRenewalIntervalInSeconds: 5
metadata-map:
instanceId: ${spring.application.name}:${server.port}
--- #zookeeper
spring:
profiles: zookeeper
cloud:
zookeeper:
connectString: localhost:2181
enabled: true
--- #consul
spring:
profiles: consul
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
#是否需要注册
register: true
#注册的实例ID (唯一标志)
instance-id: ${spring.application.name}:${server.port}
#服务的名称
service-name: ${spring.application.name}
#服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务的请求ip
ip-address: 127.0.0.1
enabled: true
application.yaml
spring:
application:
name: gateway
autoconfigure:
exclude: org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration
cloud:
gateway:
routes:
- id : oauth
uri: lb://AUTH-SERVER
predicates:
- Path=/oauth/*
- id: user
uri: lb://USER
predicates:
- Path=/user/**
filters:
- StripPrefix=1
#默认暴露所有的节点给 adminServer 生产上谨慎使用 可增加认证
management:
endpoints:
web:
exposure:
#暴露hystrix监控端点 hystrix.stream
include: '*'
endpoint:
health:
show-details: always
3.启动类
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
4. 安全的配置 (这个配置是必须加的 过滤到csrf)
gateway是用的webflux 和javax包下filter会冲突 注解这里使用 EnableWebFluxSecurity
WebSecurityConfig
@EnableWebFluxSecurity
@Configuration
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain webFluxFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/**").permitAll()
//option 请求默认放行
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.and()
.formLogin()
;
return http.build();
}
}
三.认证中心
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.style</groupId>
<artifactId>tiger</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>auth-server</name>
<description>auth-server</description>
<dependencies>
<!-- eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- consul-discovery-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!-- oauth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.yaml配置
bootstrap.yaml
server:
port: 20110
spring:
application:
name: auth-server
cloud:
zookeeper:
# zookeeper 服务发现与注册失效(默认)
enabled: false
consul:
# consul 服务发现与注册失效(默认)
enabled: false
profiles:
#切换不同 环境 使用zookeeper 或者consul
active: eureka
eureka:
client:
# Eureka 服务发现与注册失效(默认)
enabled: false
--- # Profile For Eureka
spring:
profiles: eureka
eureka:
server: # 官方不存在的配置(自定义配置)
host: 127.0.0.1
port: 20020
client:
service-url:
#注册中心地址
defaultZone: http://localhost:20020/eureka
#多注册中心
# defaultZone: http://localhost:20021/eureka,http://localhost:20022/eureka,http://localhost:20023/eureka
# 5 秒轮训一次
registryFetchIntervalSeconds: 5
enabled: true
instance:
# eureka client发送心跳给server端后,续约到期时间(默认90秒)
leaseExpirationDurationInSeconds: 10
#发送心跳续约间 5秒 发一次 心跳
leaseRenewalIntervalInSeconds: 5
metadata-map:
instanceId: ${spring.application.name}:${server.port}
--- #zookeeper
spring:
profiles: zookeeper
cloud:
zookeeper:
connectString: localhost:2181
enabled: true
--- #consul
spring:
profiles: consul
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
#是否需要注册
register: true
#注册的实例ID (唯一标志)
instance-id: ${spring.application.name}:${server.port}
#服务的名称
service-name: ${spring.application.name}
#服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务的请求ip
ip-address: 127.0.0.1
enabled: true
application.yml
spring:
application:
name: auth-server
autoconfigure:
exclude: org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration
#默认暴露所有的节点给 adminServer 生产上谨慎使用 可增加认证
management:
endpoints:
web:
exposure:
#暴露hystrix监控端点 hystrix.stream
include: '*'
endpoint:
health:
show-details: always
3.启动类配置
@SpringBootApplication
@EnableDiscoveryClient
public class AuthServerApplication {
public static void main(String[] args) {
SpringApplication.run(AuthServerApplication.class, args);
}
}
目录结构如上
AuthorizationServerConfig
客户端信息存于内存中
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
//允许token请求调用的请求类型
.allowedTokenEndpointRequestMethods(HttpMethod.POST, HttpMethod.GET)
//认证管理器
.authenticationManager(authenticationManager)
//token
.tokenServices(tokenServices())
//认证码
.authorizationCodeServices(authorizationCodeServices())
;
}
@Bean
public AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
//认证管理器
tokenServices.setAuthenticationManager(authenticationManager);
//客户端信息
tokenServices.setClientDetailsService(clientDetailsService);
//jwt token存储
tokenServices.setTokenStore(tokenStore);
//token增强
TokenEnhancerChain tokenEnhancer = new TokenEnhancerChain();
tokenEnhancer.setTokenEnhancers(Collections.singletonList(jwtAccessTokenConverter));
tokenServices.setTokenEnhancer(tokenEnhancer);
//支持刷新token
tokenServices.setSupportRefreshToken(true);
//token 有效期 2小时
tokenServices.setAccessTokenValiditySeconds(2 * 60 * 60);
// 刷新token有效期 7天
tokenServices.setRefreshTokenValiditySeconds(7 * 24 * 60 * 60);
return tokenServices;
}
/**
* 授权码 这里使用内存存储
*
* @return AuthorizationCodeServices
*/
@Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
/**
* 自定义 加密器
*
* @return PasswordEncoder
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 客户端的信息
*
* @param clients clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//配置内存中的 client
clients.inMemory()
.withClient("admin")
.secret(new BCryptPasswordEncoder().encode("MyStyle"))
//客户端允许的授权模式
.authorities("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
//允许的授权范围
.scopes("all","read","write")
//验证回调地址
.redirectUris("https://www.baidu.com")
.and()
.withClient("user")
.secret(new BCryptPasswordEncoder().encode("MyStyle"))
//客户端允许的授权模式
.authorities("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
//允许的授权范围
.scopes("read")
//验证回调地址
.redirectUris("https://www.baidu.com")
.and()
.build();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security
//oauth/token_key是公开
.tokenKeyAccess("permitAll()")
//oauth/check_token公开
.checkTokenAccess("permitAll()")
//表单认证(申请令牌)
.allowFormAuthenticationForClients()
;
}
}
SecurityConfig
定义了两个用户都存于内存中
package com.style.auth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
* @author leon
* @date 2020-09-21 13:45:17
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.anyRequest().authenticated();
;
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
//内存模式下创建的用户
//权限列表
UserDetails admin = User.withUsername("admin")
.password(new BCryptPasswordEncoder().encode("123456"))
//角色
.roles("ADMIN", "DEVELOPER")
//权限
.authorities("get","update")
.build();
//开发者
UserDetails developer = User.withUsername("developer")
.password(new BCryptPasswordEncoder().encode("123456"))
//角色
.roles("DEVELOPER")
//权限
.authorities("get")
.build();
InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
userDetailsManager.createUser(admin);
userDetailsManager.createUser(developer);
return userDetailsManager;
}
}
token配置
TokenConfig
@Configuration
public class TokenConfig {
private static final String SIGN_KEY = "MyStyle";
/**
* jwt token 存储
*
* @return TokenStore
*/
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
/**
* jwt tokenConvert
*
* @return JwtAccessTokenConverter
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey(SIGN_KEY);
return jwtAccessTokenConverter;
}
}
四.用户中心
用户中心作为资源服务器 校验token以及权限
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.style</groupId>
<artifactId>tiger</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>user</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>user</name>
<description>user</description>
<dependencies>
<!-- eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- consul-discovery-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!-- oauth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.yaml配置文件
bootstrap.yaml
server:
port: 20080
spring:
application:
name: user
cloud:
zookeeper:
# zookeeper 服务发现与注册失效(默认)
enabled: false
consul:
# consul 服务发现与注册失效(默认)
enabled: false
profiles:
#切换不同 环境 使用zookeeper 或者consul
active: eureka
eureka:
client:
# Eureka 服务发现与注册失效(默认)
enabled: false
--- # Profile For Eureka
spring:
profiles: eureka
eureka:
server: # 官方不存在的配置(自定义配置)
host: 127.0.0.1
port: 20020
client:
service-url:
#注册中心地址
#多注册中心
# defaultZone: http://localhost:20021/eureka,http://localhost:20022/eureka,http://localhost:20023/eureka
defaultZone: http://localhost:20020/eureka
# 5 秒轮训一次
registryFetchIntervalSeconds: 5
enabled: true
instance:
# eureka client发送心跳给server端后,续约到期时间(默认90秒)
leaseExpirationDurationInSeconds: 10
#发送心跳续约间 5秒 发一次 心跳
leaseRenewalIntervalInSeconds: 5
metadata-map:
instanceId: ${spring.application.name}:${server.port}
--- #zookeeper
spring:
profiles: zookeeper
cloud:
zookeeper:
connectString: localhost:2181
enabled: true
--- #consul
spring:
profiles: consul
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
#是否需要注册
register: true
#注册的实例ID (唯一标志)
instance-id: ${spring.application.name}:${server.port}
#服务的名称
service-name: ${spring.application.name}
#服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务的请求ip
ip-address: 127.0.0.1
enabled: true
application.yaml
spring:
application:
name: user
autoconfigure:
exclude: org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration
#默认暴露所有的节点给 adminServer 生产上谨慎使用 可增加认证
management:
endpoints:
web:
exposure:
#暴露hystrix监控端点 hystrix.stream
include: '*'
endpoint:
health:
show-details: always
整体结构
3.启动文件
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
4. 资源服务配置
ResourceServerConfig
@EnableResourceServer
@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
public static final String RESOURCE_ID = "resource";
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID)
.tokenStore(tokenStore)
.stateless(true)
;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/update").access("hasAuthority('update')")
.antMatchers("/get").access("hasAuthority('get')")
.antMatchers("/info").permitAll()
.anyRequest().authenticated();
}
}
WebSecurityConfig
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated();
}
}
TokenConfig
@Configuration
public class TokenConfig {
private static final String VERIFY_KEY = "MyStyle";
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setVerifierKey(VERIFY_KEY);
jwtAccessTokenConverter.setSigningKey(VERIFY_KEY);
return jwtAccessTokenConverter;
}
}
AuthController
验证的测试接口
@RestController
public class AuthController {
@GetMapping("/get")
public String get() {
return "获取接口";
}
@PostMapping("/update")
public String update() {
return "更新接口";
}
@GetMapping("/info")
public String info() {
return "详情 自由查看 不受限制";
}
}
update 接口需要有update 权限 get 接口需要有 get权限
项目到此搭建完成
首先启动注册中心 在启动网关 认证中心 用户中心
通过网关访问 user/get
返回未正常 该接口是需要添加token 才可以访问
通过网关获取一个token
获取token成功
在拿着token 去调用 /user/get
调用成功
在尝试调用下 /user/update
访问被拒绝
update 接口需要 update 权限
再次调用获取token接口 这次使用admin 用户
用新的token 去调用 /user/update
调用成功
再来测试下 /user/info
不携带token进行请求
成功
到此结束
祝大家国庆快乐!!!