init
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 "异常状态";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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("×tamp=%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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 = "服务状态通知";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
59
blade-ops/blade-admin/src/main/resources/bootstrap.yml
Normal file
59
blade-ops/blade-admin/src/main/resources/bootstrap.yml
Normal 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
|
||||
Reference in New Issue
Block a user