This commit is contained in:
kk
2026-07-07 18:05:54 +08:00
commit d4ef46bf97
743 changed files with 159169 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
FROM bladex/alpine-java:openjdk17_cn_slim
LABEL maintainer="bladejava@qq.com"
RUN mkdir -p /blade/admin
WORKDIR /blade/admin
EXPOSE 7002
COPY ./target/blade-admin.jar ./app.jar
ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
CMD ["--spring.profiles.active=test"]

View File

@@ -0,0 +1,21 @@
## SDK下载
#### Java SDK 下载
下载SDK: https://open-doc.dingtalk.com/microapp/faquestions/vzbp02
## 配置项
#### bootstrap.yml
```
# 监控的相关配置
monitor:
ding-talk:
enabled: false
# 用于自定义域名,默认会自动填充为 http://ip:port
link: http://localhost:${server.port}
# 钉钉配置的令牌
access-token: xxx
# 如果采用密钥形式,需要添加,否则需要去掉该参数
secret: xxx
```

View File

@@ -0,0 +1,109 @@
<?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>blade-ops</artifactId>
<groupId>org.springblade</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>blade-admin</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>
<dependencies>
<!--Blade-->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-common</artifactId>
<exclusions>
<exclusion>
<groupId>org.springblade</groupId>
<artifactId>blade-core-launch</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-launch</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-prometheus</artifactId>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<!--Admin-Server-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!--Security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>-->
<!--Taobao-Sdk-->
<dependency>
<groupId>com.taobao</groupId>
<artifactId>taobao-sdk</artifactId>
<version>20201116</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>${docker.fabric.skip}</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,48 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.admin;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springblade.core.launch.BladeApplication;
import org.springblade.core.launch.constant.AppConstant;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* admin启动器
*
* @author Chill
*/
@EnableAdminServer
@EnableDiscoveryClient
@SpringBootApplication
public class AdminApplication {
public static void main(String[] args) {
BladeApplication.run(AppConstant.APPLICATION_ADMIN_NAME, AdminApplication.class, args);
}
}

View File

@@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.admin.config;
import org.springblade.admin.dingtalk.MonitorProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 启动器
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(MonitorProperties.class)
public class AdminConfiguration {
}

View File

@@ -0,0 +1,61 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.config;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import org.springblade.admin.dingtalk.DingTalkNotifier;
import org.springblade.admin.dingtalk.DingTalkService;
import org.springblade.admin.dingtalk.MonitorProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.reactive.function.client.WebClient;
/**
* 钉钉自动配置
*
* @author L.cm
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "monitor.ding-talk.enabled", havingValue = "true")
public class DingTalkConfiguration {
@Bean
public DingTalkService dingTalkService(MonitorProperties properties,
WebClient.Builder builder) {
return new DingTalkService(properties, builder.build());
}
@Bean
public DingTalkNotifier dingTalkNotifier(MonitorProperties properties,
DingTalkService dingTalkService,
InstanceRepository repository,
Environment environment) {
return new DingTalkNotifier(dingTalkService, properties, environment, repository);
}
}

View File

@@ -0,0 +1,96 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.config;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springblade.admin.security.InternalAuthorizationManager;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import java.net.URI;
/**
* 监控安全配置
*
* @author L.cm
*/
@EnableWebFluxSecurity
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AdminServerProperties.class)
public class SecurityConfiguration {
private final String contextPath;
public SecurityConfiguration(AdminServerProperties adminServerProperties) {
this.contextPath = adminServerProperties.getContextPath();
}
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
// @formatter:off
RedirectServerAuthenticationSuccessHandler successHandler = new RedirectServerAuthenticationSuccessHandler();
successHandler.setLocation(URI.create(contextPath + "/"));
return http
// 明确调用headers()方法进行配置
.headers(headers -> headers
// 禁用frameOptions
.frameOptions(ServerHttpSecurity.HeaderSpec.FrameOptionsSpec::disable)
)
// 配置授权规则
.authorizeExchange(exchanges -> exchanges
.pathMatchers(
contextPath + "/assets/**",
contextPath + "/login",
contextPath + "/v1/agent/**",
contextPath + "/v1/catalog/**",
contextPath + "/v1/health/**"
).permitAll()
.pathMatchers(contextPath + "/actuator", contextPath + "/actuator/**")
.access(new InternalAuthorizationManager())
.anyExchange().authenticated()
)
// 配置表单登录
.formLogin(formLogin -> formLogin
.loginPage(contextPath + "/login")
.authenticationSuccessHandler(successHandler)
)
// 配置登出
.logout(logout -> logout
.logoutUrl(contextPath + "/logout")
)
// 禁用HTTP Basic认证
.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
// 禁用CSRF
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
// @formatter:on
}
}

View File

@@ -0,0 +1,114 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.dingtalk;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.domain.values.Registration;
import de.codecentric.boot.admin.server.domain.values.StatusInfo;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.lang.NonNull;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
/**
* 服务上下线告警
*
* <p>
* 注意AbstractStatusChangeNotifier 这个事件有毛病
* </p>
*
* @author L.cm
*/
@Slf4j
public class DingTalkNotifier extends AbstractEventNotifier {
private final DingTalkService dingTalkService;
private final MonitorProperties properties;
private final Environment environment;
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public DingTalkNotifier(DingTalkService dingTalkService, MonitorProperties properties,
Environment environment, InstanceRepository repository) {
super(repository);
this.dingTalkService = dingTalkService;
this.properties = properties;
this.environment = environment;
}
@NonNull
@Override
protected Mono<Void> doNotify(@NonNull InstanceEvent event, @NonNull Instance instance) {
if (event instanceof InstanceStatusChangedEvent) {
// 构造请求结构
return createAndPushMsg(event, instance);
}
return Mono.empty();
}
private Mono<Void> createAndPushMsg(InstanceEvent event, Instance instance) {
Registration registration = instance.getRegistration();
// 服务名
String appName = registration.getName();
// 服务地址
String serviceUrl = registration.getServiceUrl();
StatusInfo status = instance.getStatusInfo();
// 时间
LocalDateTime localDateTime = LocalDateTime.ofInstant(event.getTimestamp(), ZoneId.systemDefault());
MonitorProperties.DingTalk dingTalk = properties.getDingTalk();
String title = dingTalk.getService().getTitle();
String message = "## **" + title + "**\n" +
"#### **【服务】** " + appName + "\n" +
"#### **【环境】** " + environment.getActiveProfiles()[0] + "\n" +
"#### **【地址】** " + serviceUrl + "\n" +
"#### **【状态】** " + statusCn(status) + "\n" +
"#### **【时间】** " + DATETIME_FORMATTER.format(localDateTime) + "\n" +
"#### **【详情】** " + dingTalk.getLink() + "\n";
return dingTalkService.pushMsg(title, message);
}
private String statusCn(StatusInfo status) {
if (status.isUp()) {
return "应用上线IS UP";
} else if (status.isDown()) {
return "应用宕机IS DOWN";
} else if (status.isOffline()) {
return "应用掉线IS OFFLINE";
} else if (status.isUnknown()) {
return "未知状态UNKNOWN";
} else {
return "异常状态";
}
}
}

View File

@@ -0,0 +1,119 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.dingtalk;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriUtils;
import reactor.core.publisher.Mono;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* 钉钉 服务
*
* @author L.cm
*/
@Slf4j
@RequiredArgsConstructor
public class DingTalkService {
private static final String DING_TALK_ROBOT_URL = "https://oapi.dingtalk.com/robot/send?access_token=";
private final MonitorProperties properties;
private final WebClient webClient;
/**
* 发送消息
*
* @param title title
* @param text 消息
*/
public Mono<Void> pushMsg(String title, String text) {
log.info("钉钉消息:[创建消息体]title:{}, text:{}", title, text);
HashMap<String, String> params = new HashMap<>(2);
params.put("title", title);
params.put("text", text);
Map<String, Object> body = new HashMap<>(2);
body.put("msgtype", "markdown");
body.put("markdown", params);
log.info("创建消息体 json{}", body);
MonitorProperties.DingTalk dingTalk = properties.getDingTalk();
String accessToken = dingTalk.getAccessToken();
if (!StringUtils.hasText(accessToken)) {
log.error("DingTalk alert config accessToken ${monitor.ding-talk.access-token} is blank.");
return Mono.empty();
}
String urlString = DING_TALK_ROBOT_URL + dingTalk.getAccessToken();
// 有私钥要签名
String secret = dingTalk.getSecret();
if (StringUtils.hasText(secret)) {
long timestamp = System.currentTimeMillis();
urlString += String.format("&timestamp=%s&sign=%s", timestamp, getSign(secret, timestamp));
}
return webClient.post()
.uri(URI.create(urlString))
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(body))
.retrieve()
.bodyToMono(String.class)
.doOnSuccess((result) -> log.info("钉钉消息:[消息返回]result:{}", result))
.then();
}
private static String getSign(String secret, long timestamp) {
String stringToSign = timestamp + "\n" + secret;
byte[] hmacSha256Bytes = digestHmac(stringToSign, secret);
return UriUtils.encode(Base64.getEncoder().encodeToString(hmacSha256Bytes), StandardCharsets.UTF_8);
}
public static byte[] digestHmac(String data, String key) {
SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
try {
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
return mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,76 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.dingtalk;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
/**
* 监控配置
*
* @author L.cm
*/
@Getter
@Setter
@RefreshScope
@ConfigurationProperties("monitor")
public class MonitorProperties {
private DingTalk dingTalk = new DingTalk();
@Getter
@Setter
public static class DingTalk {
/**
* 启用钉钉告警,默认为 true
*/
private boolean enabled = false;
/**
* 钉钉机器人 token
*/
private String accessToken;
/**
* 签名:如果有 secret 则进行签名,兼容老接口
*/
private String secret;
/**
* 地址配置
*/
private String link;
private Service service = new Service();
}
@Getter
@Setter
public static class Service {
/**
* 服务 状态 title
*/
private String title = "服务状态通知";
}
}

View File

@@ -0,0 +1,84 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.admin.security;
import org.springblade.core.launch.utils.INetUtil;
import org.springframework.http.HttpHeaders;
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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.InetSocketAddress;
import java.util.Optional;
/**
* 内网认证管理,内网放行,外网认证
*
* @author L.cm
*/
public class InternalAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
private static final String HEADER_X_FORWARDED_FOR = "X-Forwarded-For";
@Override
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext context) {
return Mono.just(getAuthorizationDecision(context));
}
private static AuthorizationDecision getAuthorizationDecision(AuthorizationContext context) {
return new AuthorizationDecision(isInternalNet(context));
}
/**
* 判断是否内网 ip 请求
*
* @param context AuthorizationContext
* @return 是否内网 ip
*/
private static boolean isInternalNet(AuthorizationContext context) {
ServerHttpRequest request = Optional.ofNullable(context)
.map(AuthorizationContext::getExchange)
.map(ServerWebExchange::getRequest)
.orElse(null);
if (request == null) {
return false;
}
HttpHeaders headers = request.getHeaders();
// 如果没有 X-Forwarded-For 代表为 admin 拉取
if (!headers.containsKey(HEADER_X_FORWARDED_FOR)) {
return true;
}
return Optional.of(request)
.map(ServerHttpRequest::getRemoteAddress)
.map(InetSocketAddress::getAddress)
.map(INetUtil::isInternalIp)
.orElse(false);
}
}

View File

@@ -0,0 +1,59 @@
server:
port: 7002
undertow:
threads:
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
io: 16
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
worker: 400
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
buffer-size: 1024
# 是否分配的直接内存
direct-buffers: true
spring:
boot:
admin:
# 忽略服务名
discovery:
ignored-services:
- consul
- serverAddr
# 自定义UI界面
ui:
# Nginx反代后的外网地址
#public-url: http://localhost:${server.port}/
# 自定义的标题
title: BladeX Monitor
# 自定义的网址
external-views:
- label: 架构官网
url: https://bladex.cn/
order: 1
iframe: true
# 用于内网安全,判断 admin proxy
instance-proxy:
ignored-headers: "X-Forwarded-For"
# 自定义登录用户名密码
security:
user:
name: blade
password: blade
# 监控的相关配置
monitor:
ding-talk:
enabled: false
# 用于自定义域名,默认会自动填充为 http://ip:port
link: http://localhost:${server.port}
# 钉钉配置的令牌
access-token: xxx
# 如果采用密钥形式,需要添加,否则需要去掉该参数
secret:
# 关闭端点
management:
endpoints:
web:
discovery:
enabled: false