mirror of
https://gitee.com/xtoon/xtoon-cloud.git
synced 2025-12-30 11:02:27 +00:00
通用模块开发
This commit is contained in:
@@ -85,4 +85,6 @@ public interface AuthConstants {
|
||||
String GRANT_TYPE_KEY = "grant_type";
|
||||
|
||||
String REFRESH_TOKEN = "refresh_token";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -84,6 +84,21 @@ public class RedisService {
|
||||
return gson.toJson(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON数据,转成Object
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<module>xtoon-register-server</module>
|
||||
<module>xtoon-sentinel-server</module>
|
||||
<module>xtoon-auth-server</module>
|
||||
<module>xtoon-gateway-server</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
||||
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.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
@@ -61,7 +61,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,8 +29,8 @@ public class AuthController {
|
||||
|
||||
@PostMapping("/token")
|
||||
public OAuth2AccessToken postAccessToken(
|
||||
Principal principal,
|
||||
@RequestParam Map<String, String> parameters
|
||||
Principal principal,
|
||||
@RequestParam Map<String, String> parameters
|
||||
) throws HttpRequestMethodNotSupportedException {
|
||||
OAuth2AccessToken oAuth2AccessToken;
|
||||
oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.xtoon.cloud.ops.auth.service;
|
||||
|
||||
import com.xtoon.cloud.common.core.constant.AuthConstants;
|
||||
import com.xtoon.cloud.ops.auth.domain.User;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -22,6 +23,6 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
@Override
|
||||
public User loadUserByUsername(String s) throws UsernameNotFoundException {
|
||||
// TODO test
|
||||
return new User(1L,"test", new BCryptPasswordEncoder().encode("123456"), true,"client",null);
|
||||
return new User(1L, "test", AuthConstants.BCRYPT + new BCryptPasswordEncoder().encode("123456"), true, "client", null);
|
||||
}
|
||||
}
|
||||
|
||||
82
xtoon-ops/xtoon-gateway-server/pom.xml
Normal file
82
xtoon-ops/xtoon-gateway-server/pom.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?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>xtoon-ops</artifactId>
|
||||
<groupId>com.xtoon.cloud</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>xtoon-gateway-server</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.xtoon.cloud</groupId>
|
||||
<artifactId>xtoon-common-core</artifactId>
|
||||
<version>${xtoon-cloud.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xtoon.cloud</groupId>
|
||||
<artifactId>xtoon-common-web</artifactId>
|
||||
<version>${xtoon-cloud.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xtoon.cloud</groupId>
|
||||
<artifactId>xtoon-common-redis</artifactId>
|
||||
<version>${xtoon-cloud.version}</version>
|
||||
</dependency>
|
||||
<!--gateway 网关依赖,内置webflux 依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
|
||||
</dependency>
|
||||
<!--注册中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!--断路器依赖-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
</dependency>
|
||||
<!-- LB 扩展 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- OAuth2资源服务器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-jose</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.xtoon.cloud.ops.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
/**
|
||||
* 网关服务
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-06-15
|
||||
**/
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class XtoonCloudGatewayApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(XtoonCloudGatewayApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.xtoon.cloud.ops.gateway.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.xtoon.cloud.common.core.constant.AuthConstants;
|
||||
import com.xtoon.cloud.common.web.constant.ResultCode;
|
||||
import com.xtoon.cloud.ops.gateway.security.AuthorizationManager;
|
||||
import com.xtoon.cloud.ops.gateway.util.WebUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 资源服务器配置
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-06-15
|
||||
**/
|
||||
@AllArgsConstructor
|
||||
@Configuration
|
||||
@EnableWebFluxSecurity
|
||||
public class ResourceServerConfig {
|
||||
|
||||
private WhiteListConfig whiteListConfig;
|
||||
|
||||
private AuthorizationManager authorizationManager;
|
||||
|
||||
@Bean
|
||||
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||
http.oauth2ResourceServer().jwt()
|
||||
.jwtAuthenticationConverter(jwtAuthenticationConverter());
|
||||
http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
|
||||
http.authorizeExchange()
|
||||
.pathMatchers(ArrayUtil.toArray(whiteListConfig.getUrls(), String.class)).permitAll()
|
||||
.anyExchange().access(authorizationManager)
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
.accessDeniedHandler(accessDeniedHandler())
|
||||
.authenticationEntryPoint(authenticationEntryPoint())
|
||||
.and().csrf().disable();
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 未授权
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
ServerAccessDeniedHandler accessDeniedHandler() {
|
||||
return (exchange, denied) -> {
|
||||
Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
|
||||
.flatMap(response -> WebUtils.getAuthFailResult(response, ResultCode.UNAUTHORIZED.getCode()));
|
||||
return mono;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* token无效或者已过期自定义响应
|
||||
*/
|
||||
@Bean
|
||||
ServerAuthenticationEntryPoint authenticationEntryPoint() {
|
||||
return (exchange, e) -> {
|
||||
Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
|
||||
.flatMap(response -> WebUtils.getAuthFailResult(response, ResultCode.UNAUTHORIZED.getCode()));
|
||||
return mono;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter() {
|
||||
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
|
||||
jwtGrantedAuthoritiesConverter.setAuthorityPrefix(AuthConstants.AUTHORITY_PREFIX);
|
||||
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(AuthConstants.JWT_AUTHORITIES_KEY);
|
||||
|
||||
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
|
||||
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
|
||||
return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xtoon.cloud.ops.gateway.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 白名单配置
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-29
|
||||
**/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "whitelist")
|
||||
public class WhiteListConfig {
|
||||
|
||||
private List<String> urls;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.xtoon.cloud.ops.gateway.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 网关
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-28
|
||||
**/
|
||||
@RestController
|
||||
public class IndexApi {
|
||||
|
||||
/**
|
||||
* 网关测试
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/")
|
||||
public Mono<String> index() {
|
||||
return Mono.just("gamma cloud gateway");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.xtoon.cloud.ops.gateway.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.nimbusds.jose.JWSObject;
|
||||
import com.xtoon.cloud.common.core.constant.AuthConstants;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 全局过滤器
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-28
|
||||
**/
|
||||
@Component
|
||||
public class AuthGlobalFilter implements GlobalFilter, Ordered {
|
||||
|
||||
// @Autowired
|
||||
// private RedisService redisService;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
|
||||
// 非JWT或者JWT为空不作处理
|
||||
String token = request.getHeaders().getFirst(AuthConstants.AUTHORIZATION_KEY);
|
||||
if (StrUtil.isBlank(token) || !token.startsWith(AuthConstants.AUTHORIZATION_PREFIX)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
// 解析JWT获取jti,以jti为key判断redis的黑名单列表是否存在,存在拦截响应token失效
|
||||
token = token.replace(AuthConstants.AUTHORIZATION_PREFIX, Strings.EMPTY);
|
||||
JWSObject jwsObject = JWSObject.parse(token);
|
||||
String payload = jwsObject.getPayload().toString();
|
||||
JSONObject jsonObject = JSONUtil.parseObj(payload);
|
||||
// String jti = jsonObject.getStr(AuthConstants.JWT_JTI);
|
||||
// Boolean isBlack = redisService.hasKey(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti);
|
||||
// if (isBlack) {
|
||||
// return WebUtils.getAuthFailResult(response, ResultCode.UNAUTHORIZED.getCode());
|
||||
// }
|
||||
|
||||
// 存在token且不是黑名单,request写入JWT的载体信息
|
||||
request = exchange.getRequest().mutate()
|
||||
.header(AuthConstants.JWT_PAYLOAD_KEY, payload)
|
||||
.build();
|
||||
exchange = exchange.mutate().request(request).build();
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.xtoon.cloud.ops.gateway.filter;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
|
||||
|
||||
/**
|
||||
* request过滤器
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-28
|
||||
**/
|
||||
@Component
|
||||
public class RequestFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
addOriginalRequestUrl(exchange, request.getURI());
|
||||
String rawPath = request.getURI().getRawPath();
|
||||
String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/"))
|
||||
.skip(1L).collect(Collectors.joining("/"));
|
||||
ServerHttpRequest newRequest = request.mutate()
|
||||
.path(newPath)
|
||||
.build();
|
||||
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
|
||||
return chain.filter(exchange.mutate().request(newRequest.mutate().build()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return -1000;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.xtoon.cloud.ops.gateway.security;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.server.authorization.AuthorizationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 鉴权管理器
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-28
|
||||
**/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
|
||||
|
||||
@Override
|
||||
public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
|
||||
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
|
||||
String restPath = request.getMethodValue() + "_" + request.getURI().getPath();
|
||||
log.info("请求路径:{}", restPath);
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
// 对应跨域的预检请求直接放行
|
||||
if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
return mono.map(auth -> new AuthorizationDecision(auth.isAuthenticated())).defaultIfEmpty(new AuthorizationDecision(false));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.xtoon.cloud.ops.gateway.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.xtoon.cloud.common.web.constant.ResultCode;
|
||||
import com.xtoon.cloud.common.web.util.Result;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* web工具类
|
||||
*
|
||||
* @author haoxin
|
||||
* @date 2021-05-29
|
||||
**/
|
||||
public class WebUtils {
|
||||
|
||||
public static Mono<Void> getAuthFailResult(ServerHttpResponse response, Integer code) {
|
||||
response.setStatusCode(HttpStatus.OK);
|
||||
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
|
||||
byte[] responseByte = new Gson().toJson(Result.error(code, ResultCode.getValue(code).getMsg())).getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = response.bufferFactory().wrap(responseByte);
|
||||
return response.writeWith(Flux.just(buffer));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
spring:
|
||||
application:
|
||||
name: xtoon-gateway-server
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
file-extension: yaml
|
||||
enabled: true
|
||||
boot:
|
||||
admin:
|
||||
client:
|
||||
url: http://localhost:5001
|
||||
username: admin
|
||||
password: admin
|
||||
instance:
|
||||
prefer-ip: true
|
||||
|
||||
management:
|
||||
health:
|
||||
redis:
|
||||
enabled: false
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
Reference in New Issue
Block a user