当前位置: 首页 > news >正文

镇江网站优化公司工作室东莞seo网站关键词优优化

镇江网站优化公司工作室,东莞seo网站关键词优优化,手机网站是怎么做的,跨境电商怎么推广引流一#xff0c;背景 Spring Boot应用中的数据库、Redis、Nacos、MQ等的用户名、连接地址、密码在配置文件中一般都是明文存储#xff0c;如果系统被系统攻破或者配置文件所在的目录读权限被破解#xff0c;又或者是动态配置文件被窃取#xff0c;内部人员或者黑客很容易通过…一背景 Spring Boot应用中的数据库、Redis、Nacos、MQ等的用户名、连接地址、密码在配置文件中一般都是明文存储如果系统被系统攻破或者配置文件所在的目录读权限被破解又或者是动态配置文件被窃取内部人员或者黑客很容易通过配置文件获取到数据库的用户名和密码进而达到非法连接数据库盗取数据的目的。 本文的目标是对配置文件的敏感信息加密同时保持对现有应用的最小改动对应用中的配置文件中的秘文配置项的使用保持和加密前一致也就是使用配置项不受到任何影响。 二SpringBoot自动配置原理分析 2.1 配置文件加载准备 我们知道SpringApplication构造器加载完Initialzers和Listenter后开始调用run(String…args)方法启动Springboot上下文。 /*** Run the Spring application, creating and refreshing a new* {link ApplicationContext}.* param args the application arguments (usually passed from a Java main method)* return a running {link ApplicationContext}*/public ConfigurableApplicationContext run(String... args) {long startTime System.nanoTime();DefaultBootstrapContext bootstrapContext createBootstrapContext();ConfigurableApplicationContext context null;configureHeadlessProperty();SpringApplicationRunListeners listeners getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments new DefaultApplicationArguments(args);// 配置文件加载入口它会去执行SpringApplication构造器加载到ListerConfigurableEnvironment environment prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner printBanner(environment);context createApplicationContext();context.setApplicationStartup(this.applicationStartup);prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);Duration timeTakenToStartup Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);callRunners(context, applicationArguments);}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {if (context.isRunning()) {Duration timeTakenToReady Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}return context;}SpringApplication#prepareEnvironment( listeners, applicationArguments), 这个方法是配置文件加载路口他会执行SpringApplication构造器加载到Listener。这里我们重要关注BootstrapApplicationListener和ConfigFileApplicationListener这两个监听器。 package org.springframework.boot.SpringApplication;private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// 给容器创建一个 environmentConfigurableEnvironment environment getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach(environment);// 执行引入jar包类路径下的META/INF/spring.factories文件到监听器listeners.environmentPrepared(bootstrapContext, environment);DefaultPropertiesPropertySource.moveToEnd(environment);Assert.state(!environment.containsProperty(spring.main.environment-prefix),Environment prefix cannot be set via properties.);// 将加载完成的环境变量信息绑定到Spring IOC容器中bindToSpringApplication(environment);if (!this.isCustomEnvironment) {EnvironmentConverter environmentConverter new EnvironmentConverter(getClassLoader());environment environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());}ConfigurationPropertySources.attach(environment);return environment;}public void multicastEvent(final ApplicationEvent event, Nullable ResolvableType eventType) {ResolvableType type eventType ! null ? eventType : this.resolveDefaultEventType(event);Executor executor this.getTaskExecutor();Iterator var5 this.getApplicationListeners(event, type).iterator();while(var5.hasNext()) {ApplicationListener? listener (ApplicationListener)var5.next();if (executor ! null) {executor.execute(() - {this.invokeListener(listener, event);});} else {// 触发BootstrapConfigFileApplicationListenerthis.invokeListener(listener, event);}}}SpringApplication#prepareEnvironment()触发执行监听器优先执行BootstrapApplicationListener监听器再执行ConfigFileApplicationListener监听器 BootstrapApplicationListener来自SpringCloud。优先级最高用于启动/建立Springcloud的应用上下文。需要注意的是到此时Springboot的上下文还未创建完成因为在创建springboot上下文的时候通过BootstrapApplicationListener去开启了springcloud上下文的创建流程。这个流程“嵌套”特别像是Bean初始化流程初始化A时A-B,就必须先去完成Bean B的初始化再回来继续完成A的初始化。在建立SpringCloud的应用的时候使用的也是SpringApplication#run()完成的所以也会走一整套SpringApplication的生命周期逻辑。这里之前就踩过坑初始化器、监听器等执行多次若只需执行一次需要自行处理。Springcloud和Springboot应用上下文都是使用ConfigFileApplicationListener来完成加载和解析的 Springboot应用上下文读取的是配置文件默认是application Springcloud应用上下文读取的外部配置文件名默认是bootstrapBootstrapApplicationListener 核心代码 Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {// 检查是否开启了SpringCloudConfigurableEnvironment environment event.getEnvironment();if (!bootstrapEnabled(environment) !useLegacyProcessing(environment)) {return;}// dont listen to events in a bootstrap context// 如果执行了Springcloud上下文触发的BootStapApplicationListener这个监听器就不执行这个监听器了 避免重复执行if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {return;}ConfigurableApplicationContext context null;String configName environment.resolvePlaceholders(${spring.cloud.bootstrap.name:bootstrap});for (ApplicationContextInitializer? initializer : event.getSpringApplication().getInitializers()) {if (initializer instanceof ParentContextApplicationContextInitializer) {context findBootstrapContext((ParentContextApplicationContextInitializer) initializer, configName);}}// 如果还未创建SpringCloud上下文实例则调用bootstrapServiceContextif (context null) {context bootstrapServiceContext(environment, event.getSpringApplication(), configName);event.getSpringApplication().addListeners(new CloseContextOnFailureApplicationListener(context));}apply(context, event.getSpringApplication(), environment);}BootstrapApplicationListener#bootstrapServiceContext()核心源码如下 private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment,final SpringApplication application, String configName) {ConfigurableEnvironment bootstrapEnvironment new AbstractEnvironment() {};MutablePropertySources bootstrapProperties bootstrapEnvironment.getPropertySources();String configLocation environment.resolvePlaceholders(${spring.cloud.bootstrap.location:});String configAdditionalLocation environment.resolvePlaceholders(${spring.cloud.bootstrap.additional-location:});MapString, Object bootstrapMap new HashMap();bootstrapMap.put(spring.config.name, configName);// if an app (or test) uses spring.main.web-application-typereactive, bootstrap// will fail// force the environment to use none, because if though it is set below in the// builder// the environment overrides itbootstrapMap.put(spring.main.web-application-type, none);if (StringUtils.hasText(configLocation)) {bootstrapMap.put(spring.config.location, configLocation);}if (StringUtils.hasText(configAdditionalLocation)) {bootstrapMap.put(spring.config.additional-location, configAdditionalLocation);}bootstrapProperties.addFirst(new MapPropertySource(BOOTSTRAP_PROPERTY_SOURCE_NAME, bootstrapMap));for (PropertySource? source : environment.getPropertySources()) {if (source instanceof StubPropertySource) {continue;}bootstrapProperties.addLast(source);}// TODO: is it possible or sensible to share a ResourceLoader?// 通过SpringApplicationBuilder构建一个SpringCloud的上下文实例SpringApplicationBuilder builder new SpringApplicationBuilder().profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment)// Dont use the default properties in this builder.registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE);final SpringApplication builderApplication builder.application();if (builderApplication.getMainApplicationClass() null) {// gh_425:// SpringApplication cannot deduce the MainApplicationClass here// if it is booted from SpringBootServletInitializer due to the// absense of the main method in stackTraces.// But luckily this methods second parameter application here// carries the real MainApplicationClass which has been explicitly// set by SpringBootServletInitializer itself already.builder.main(application.getMainApplicationClass());}if (environment.getPropertySources().contains(refreshArgs)) {// If we are doing a context refresh, really we only want to refresh the// Environment, and there are some toxic listeners (like the// LoggingApplicationListener) that affect global static state, so we need a// way to switch those off.builderApplication.setListeners(filterListeners(builderApplication.getListeners()));}builder.sources(BootstrapImportSelectorConfiguration.class);// 调用Springcloud上下文实例的run方法使用的也是SpringApplication#run()方法//这个过程会将之前的步骤在执行一次final ConfigurableApplicationContext context builder.run();// gh-214 using spring.application.namebootstrap to set the context id via// ContextIdApplicationContextInitializer prevents apps from getting the actual// spring.application.name// during the bootstrap phase.context.setId(bootstrap);// Make the bootstrap context a parent of the app contextaddAncestorInitializer(application, context);// It only has properties in it now that we dont want in the parent so remove// it (and it will be added back later)bootstrapProperties.remove(BOOTSTRAP_PROPERTY_SOURCE_NAME);mergeDefaultProperties(environment.getPropertySources(), bootstrapProperties);return context;}调用springcloud上下文实例的run方法会将之前的步骤在重复执行一次程序又执行到遍历监听器并发这里了重点关注一下ConfigFileApplicationListener这个监听器会完成配置文件的加载。进入断点里面之前我先做一些说明。因为这里会创建Springcloud和Springboot两个上下文实例 由于Springboot和Springcloud上下文实例加载配置文件的流程都是相似的这里我们就讲解Springboot容器配置文件的加载过程。 bootstrap.yml 可以用来定义应用级别的 应用程序特有配置信息可以用来配置后续各个模块中需使用的公共参数等。如果application.yml的内容标签与bootstrap的标签一致application会覆盖bootstrap, 而application.yml 里面的内容可以动态替换。 2.2 配置文件加载解析 EnvironmentPostProcessorApplicationListener#onApplicationEnvironmentPreparedEvent()根据上面的流程可知程序会触发EnvironmentPostProcessorApplicationListener的onApplicationEvent方法从而加载配置文件。 获取所有的onApplicationEnvironmentPreparedEvent后置处理器并执行后置处理器方法 Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent environmentPreparedEvent) {onApplicationEnvironmentPreparedEvent(environmentPreparedEvent);}if (event instanceof ApplicationPreparedEvent) {onApplicationPreparedEvent();}if (event instanceof ApplicationFailedEvent) {onApplicationFailedEvent();}}private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment event.getEnvironment();SpringApplication application event.getSpringApplication();for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(),event.getBootstrapContext())) {postProcessor.postProcessEnvironment(environment, application);}} Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {if (PropertyUtils.bootstrapEnabled(environment)) {addPropertySources(environment, application.getResourceLoader());}}/*** Add config file property sources to the specified environment.* param environment the environment to add source to* param resourceLoader the resource loader* see #addPostProcessors(ConfigurableApplicationContext)*/protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {RandomValuePropertySource.addToEnvironment(environment);new Loader(environment, resourceLoader).load();} BootstrapConfigFileApplicationListener#addPropertySources()流程继续执行到addPropertySources这里会去新建一个Loader内部类并执行load方法。 protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {RandomValuePropertySource.addToEnvironment(environment);new Loader(environment, resourceLoader).load();} BootstrapConfigFileApplicationListener#Loader#load()方法 private class Loader {private final Log logger BootstrapConfigFileApplicationListener.this.logger;private final ConfigurableEnvironment environment;private final PropertySourcesPlaceholdersResolver placeholdersResolver;private final ResourceLoader resourceLoader;private final ListPropertySourceLoader propertySourceLoaders;private DequeProfile profiles;private ListProfile processedProfiles;private boolean activatedProfiles;private MapProfile, MutablePropertySources loaded;private MapDocumentsCacheKey, ListDocument loadDocumentsCache new HashMap();Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {this.environment environment;this.placeholdersResolver new PropertySourcesPlaceholdersResolver(this.environment);this.resourceLoader (resourceLoader ! null) ? resourceLoader : new DefaultResourceLoader(null);this.propertySourceLoaders SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,this.resourceLoader.getClassLoader());}void load() {FilteredPropertySource.apply(this.environment, DefaultPropertiesPropertySource.NAME, LOAD_FILTERED_PROPERTY,this::loadWithFilteredProperties);}初始化initializeProfiles private void initializeProfiles() {// The default profile for these purposes is represented as null. We add it// first so that it is processed first and has lowest priority.//默认添加一个null这样的目的是为了先出来加载application.xxx文件优先级最低this.profiles.add(null);// 把当前environment中已经加载的系统级别的配置文件包装到Binder容器中Binder binder Binder.get(this.environment);// 在Binder容器中找到spring.profiles.actives配置列表SetProfile activatedViaProperty getProfiles(binder, ACTIVE_PROFILES_PROPERTY);// 在Binder容器中找到spring.profiles.include配置列表SetProfile includedViaProperty getProfiles(binder, INCLUDE_PROFILES_PROPERTY);//environment的spring.profiles.active属性中存在且activeViaProperty和includedViaProProperty Property不存在的配置ListProfile otherActiveProfiles getOtherActiveProfiles(activatedViaProperty, includedViaProperty);// 将解析出的profile依次按照otherActiveProfiles、includeViaProperty和activeViaProperty的先后次序//将添加进去的先被加载但Spring读取使用优先级最低因为最后一次进行reverse操作this.profiles.addAll(otherActiveProfiles);// Any pre-existing active profiles set via property sources (e.g.// System properties) take precedence over those added in config files.this.profiles.addAll(includedViaProperty);addActiveProfiles(activatedViaProperty);// 在系统中未加载到的profile此时profiles中就只有进入此方法默认添加的null// 此时就给profile添加一个“default”若在application.xxx中仍未配置指定的profile则会去加载此时添加的“default”//若application.xxx中配置了指定的profile则会将“default”从profile移除if (this.profiles.size() 1) { // only has null profilefor (String defaultProfileName : getDefaultProfiles(binder)) {Profile defaultProfile new Profile(defaultProfileName, true);this.profiles.add(defaultProfile);}}}根据源码调用链路可知程序继续调用Loader#load( profile, filterFactory, consumer)Loader#load(location, name, profile, filterFactory, consumer) location总共分为classpath:/,classpath:/config/,file:./,file:./config/配置文件可配置的地址加载优先级为倒序。name默认为“application”。profile若当前解析的不是spring.profiles.active指定的配置文件时默认为“null”否则为- spring.profiles.active指定的值。filterFactoryconsumer将加载的document添加到Loader#loaded属性集合中用于最后的配置文件优先级排序。 private void load(String location, String name, Profile profile,DocumentFilterFactory filterFactory, DocumentConsumer consumer) {if (!StringUtils.hasText(name)) {for (PropertySourceLoader loader : this.propertySourceLoaders) {if (canLoadFileExtension(loader, location)) {load(loader, location, profile,filterFactory.getDocumentFilter(profile), consumer);return;}}}// 临时存储判断是否已经加载过了某种扩展名类型propertis、xml、yml、yaml// 的的配置避免重复加载SetString processed new HashSet();// this.propertySourceLoaders分为PropertiesPropertySourceLoader和YamlPropertySourceLoader两种// PropertiesPropertySourceLoader解析properties、xml类型配置// YamlPropertySourceLoader解析yml、yaml类型for (PropertySourceLoader loader : this.propertySourceLoaders) {// fileExtension由loder类型决定优先级顺序为properties xml yml ymal// 配置文件拼接规则location name - profile fileExtension;for (String fileExtension : loader.getFileExtensions()) {if (processed.add(fileExtension)) {loadForFileExtension(loader, location name, . fileExtension,profile, filterFactory, consumer);}}} } Loader#load(loader, location, profile,filter, consumer)核心解析方法根据已拼接好地址去获取配置文件例如classpath:/application-dev.yml 文件不存在结束当前方法继续执行下一次循环文件存在解析配置文件将解析到的配置文件保存到Loader#loaded变量中文件存在时还需要尝试获取spring.profiles.active属性规则如下 1若没有配置该属性值则加载完当前fileExtension类型的配置eg application.properties、xml、yml、yaml后就不再尝试解析其他fileExtension类型的配置文件了此时系统就默认使用加载到的application.properties/yml配置2若配置了该属性值则读取该属性值当前配置的是dev将其添加到Loaderprofiles属性中就是第三步while循环的那个profiles变量值同时Loader会将activatedProfiles属性值改为true来标记系统已有active这个属性值Loader也不会再去解析该配置文件了private void load(PropertySourceLoader loader, String location, Profile profile, DocumentFilter filter, DocumentConsumer consumer) {try {// 根据拼接的配置文件地址来加载配置文件// 例如location为classpath:application.ymlResource resource this.resourceLoader.getResource(location);// 配置文件不存在则返回继续查找if (resource null || !resource.exists()) {if (this.logger.isTraceEnabled()) {StringBuilder description getDescription(Skipped missing config , location, resource, profile);this.logger.trace(description);}return;}String name applicationConfig: [ location ];// 解析配置文件并读取spring.profiles.active属性将读取到的active属性赋值给document.getActiveProfiles()ListDocument documents loadDocuments(loader, name, resource);// 保存已解析的配置文件ListDocument loaded new ArrayList();for (Document document : documents) {if (filter.match(document)) {// 1、将解析到的spring.profiles.active添加到profiles中下一次while循环就解析profile// 比如说这里的active为dev则接下来就拼接并加载dev的配置文件// 2、将activatedProfiles属性设置为true标注已经解析到了active属性后续// 就算在后面的配置文件中解析到active属性也不会再加载改配置// 3、移除profiles中的“default”配置后续将不会再加载application-defalut.yml配置addActiveProfiles(document.getActiveProfiles());// 将本次配置文件中加载到的“spring.profiles.include”中配置profile添加到profiles队列头部// 队列头部的配置将会先被加载但配置使用的优先级低于后面加载的配置文件因为配置文件加载完后会执行reverse操作addIncludedProfiles(document.getIncludeProfiles());// 添加到已加载的配置文件loaded.add(document);}}Collections.reverse(loaded);if (!loaded.isEmpty()) {// 将加载的document添加到Loader#loaded属性集合中用于最后的配置文件优先级排序// 根据当前加载顺序进行倒序排由于application.yml比application-dev.yml// 先加载所以倒序后指定的application-dev.yml配置优先级更高loaded.forEach((document) - consumer.accept(profile, document));if (this.logger.isDebugEnabled()) {StringBuilder description getDescription(Loaded config file ,location, resource, profile);this.logger.debug(description);}}} catch (Exception ex) {throw new IllegalStateException(Failed to load property source from location location , ex);} } 经过上面的步骤将所有的配置文件解析并添加到Loader#loaded属性中后继续执行第三步中addLoadedPropertySource()方法该方法会将现有loaded中保存的配置文件倒叙后依次添加到environment中。 private void addLoadedPropertySources() {// 获取环境变量中已加载的配置信息MutablePropertySources destination this.environment.getPropertySources();// 获取已本次Loader加载到的配置文件ListMutablePropertySources loaded new ArrayList(this.loaded.values());// 将已加载的配置文件倒序更改优先级spring.profile.active指定的优先级最高Collections.reverse(loaded);// 标注上一个添加到environment中的配置文件用于确定当前配置文件插入的位置String lastAdded null;// 利用set集合的属性避免配置文件的重复添加SetString added new HashSet();// 遍历并将配置添加到environment中for (MutablePropertySources sources : loaded) {for (PropertySource? source : sources) {if (added.add(source.getName())) {// 将已加载的配置文件添加到environment的MutablePropertySources中addLoadedPropertySource(destination, lastAdded, source);lastAdded source.getName();}}} }private void addLoadedPropertySource(MutablePropertySources destination, String lastAdded, PropertySource? source) {if (lastAdded null) {// 如果系统中存在defaultProperties这个配置则将第一个优先级的配置文件添加到这个配置文件的顺序之前// 如果系统中不存在defaultProperties这个配置则将第一个优先级的配置文件添加到environment中的最后一个// defaultProperties实际为bootstrap.ymlif (destination.contains(DEFAULT_PROPERTIES)) {destination.addBefore(DEFAULT_PROPERTIES, source);} else {destination.addLast(source);}} else {// 将当前配置文件添加到上一个配置文件之后destination.addAfter(lastAdded, source);} }三 通过PropertySourceLoader 实现自定义load配置文件的方式植入加解密 3.1 重写yaml格式的文件加载类 新建文件 resourece/META-INF/spring.factories org.springframework.boot.env.PropertySourceLoader\ com.ksher.framework.secret.parser.SecretYamlPropertySourceLoader重写yamlSourceLoader package com.ksher.framework.secret.parser;import com.alibaba.cloud.nacos.parser.AbstractPropertySourceLoader; import com.ksher.framework.secret.kms.KmsSecret; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.env.OriginTrackedMapPropertySource; import org.springframework.core.Ordered; import org.springframework.core.env.PropertySource; import org.springframework.core.io.Resource; import org.springframework.util.ClassUtils;import java.io.IOException; import java.util.*;public class SecretYamlPropertySourceLoader extends AbstractPropertySourceLoaderimplements Ordered {private static final Logger log LoggerFactory.getLogger(SecretYamlPropertySourceLoader.class);/*** Get the order value of this object.* p* Higher values are interpreted as lower priority. As a consequence, the object with* the lowest value has the highest priority (somewhat analogous to Servlet* {code load-on-startup} values).* p* Same order values will result in arbitrary sort positions for the affected objects.* return the order value* see #HIGHEST_PRECEDENCE* see #LOWEST_PRECEDENCE*/Overridepublic int getOrder() {return Integer.MIN_VALUE;}Overridepublic String[] getFileExtensions() {return new String[] { yml, yaml };}Overridepublic ListPropertySource? load(String name, Resource resource) throws IOException {if (!ClassUtils.isPresent(org.yaml.snakeyaml.Yaml, getClass().getClassLoader())) {throw new IllegalStateException(Attempted to load name but snakeyaml was not found on the classpath);}ListMapString, Object loaded new OriginTrackedYamlLoader(resource).load();if (loaded.isEmpty()) {return Collections.emptyList();}ListPropertySource? propertySources new ArrayList(loaded.size());for (int i 0; i loaded.size(); i) {String documentNumber (loaded.size() ! 1) ? (document # i ) : ;MapString, Object stringObjectMap loaded.get(i);for (String s : stringObjectMap.keySet()) {try {String value stringObjectMap.get(s).toString();if (value.startsWith(Encrypted:)) {int prefixLength Encrypted:.length();String extractedString value.substring(prefixLength);String decrypt KmsSecret.dncrypt(extractedString);stringObjectMap.put(s, decrypt);}} catch (Exception e) {log.error(KmsSecret decrypt failed, e);}}log.info(loaded properties is {}, stringObjectMap);propertySources.add(new OriginTrackedMapPropertySource(name documentNumber,stringObjectMap, true));}return propertySources;}Overrideprotected ListPropertySource? doLoad(String name, Resource resource) throws IOException {if (!ClassUtils.isPresent(org.yaml.snakeyaml.Yaml, getClass().getClassLoader())) {throw new IllegalStateException(Attempted to load name but snakeyaml was not found on the classpath);}ListMapString, Object loaded new OriginTrackedYamlLoader(resource).load();if (loaded.isEmpty()) {return Collections.emptyList();}ListPropertySource? propertySources new ArrayList(loaded.size());for (int i 0; i loaded.size(); i) {String documentNumber (loaded.size() ! 1) ? (document # i ) : ;propertySources.add(new OriginTrackedMapPropertySource(name documentNumber,Collections.unmodifiableMap(loaded.get(i)), true));}return propertySources;} } 植入解密 Overridepublic ListPropertySource? load(String name, Resource resource) throws IOException {if (!ClassUtils.isPresent(org.yaml.snakeyaml.Yaml, getClass().getClassLoader())) {throw new IllegalStateException(Attempted to load name but snakeyaml was not found on the classpath);}ListMapString, Object loaded new OriginTrackedYamlLoader(resource).load();if (loaded.isEmpty()) {return Collections.emptyList();}ListPropertySource? propertySources new ArrayList(loaded.size());for (int i 0; i loaded.size(); i) {String documentNumber (loaded.size() ! 1) ? (document # i ) : ;MapString, Object stringObjectMap loaded.get(i);for (String s : stringObjectMap.keySet()) {try {String value stringObjectMap.get(s).toString();if (value.startsWith(Encrypted:)) {// 解密植入int prefixLength Encrypted:.length();String extractedString value.substring(prefixLength); // AESUtil.decrypt(extractedString)String decrypt KmsSecret.dncrypt(extractedString);stringObjectMap.put(s, decrypt);}} catch (Exception e) {log.error(KmsSecret decrypt failed, e);}}log.info(loaded properties is {}, stringObjectMap);propertySources.add(new OriginTrackedMapPropertySource(name documentNumber,stringObjectMap, true));}return propertySources;}解析yaml文件 test:secret:mysql:# 加密数据user: Encrypted: E2Z3gvXufRIwuif2RfgkNQdemo: Encrypted: Encrypted: E2Z3gvXufRIwuif2RfgkNQpassword: Encrypted: E2Z3gvXufRIwuif2RfgkNQ spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://10.10.7.11:3306/ksher_config_dev?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtrueusername: Encrypted: E2Z3gvXufRIwuif2RfgkNQpassword: Encrypted: E2Z3gvXufRIwuif2RfgkNQ放入springboot的环境变量中 没有解密前数据 四github地址 secret-spring-boot-starter
http://www.dnsts.com.cn/news/74364.html

相关文章:

  • 石家庄做网站建设公司天津设计公司招聘
  • 怎么用代码做网站推荐做ppt兼职的网站
  • 网站建设怎么打广告做海淘的网站做海淘的网站
  • 制作物流网站seo常见的优化技术
  • 长沙优化网站排名网站分析及推广方案
  • 用邮箱做网站开封网站推广公司
  • 网站个人主页怎么做广东智能网站建设配件
  • 北京企业网站模板建站开发企业网站建设有几种形式
  • 做网站需要用什么系统wordpress 数据迁移
  • 美橙网站建设教程北京网站建设 知乎
  • 做网站前期构架图百度seo推广软件
  • 网站建设在哪个会计科目核算做网站运维应该看的书
  • 做邀请函用哪个网站好呢购物网页设计模板html
  • 西安建设门户网站网站到期后如何转域名
  • 免费手机网站制作方法北京梵客家装官网
  • 好的网站模板南京高端网站建设公司
  • 网站开发师是做什么的怎样做让百度收录网站域名
  • 泉州网站建设公司首选公司网页制做
  • 如何做网站认证iis网站物理路径
  • 同主机网站查询云建站管理区
  • 用vs做网站在安装时要勾选新任上海市领导调整公示
  • 健康私人定制网站怎么做网站开发技术人员
  • 网站有哪些内容html5 动态效果 手机网站
  • 品牌网站建设新闻wordpress 显示指定文章
  • 怎样做网站 网页网页设计与制作教程第二版张晓蕾课后答案
  • 网站如何做外链2018建模网站
  • godaddy主机到网站软件技术ui设计专业怎么样
  • 群晖做网站网站项目计划书范文
  • 和动物做的网站大连网站建设连城传媒
  • 建设网站怎么查明细温室网站建设