获取SpringCloud Config的真实配置

​​
个人博客:https://everspring.github.io/
公众号:爱历史的IT男

文章目录

  • 环境
  • 正文
    • 1. 无加密
    • 2. 有加密
      • 1. 通过URI的userInfo实现
      • 2. 先Base65加密,请求时在Header中带上

环境

代码样例为:SpringCloud 1.5.22
Eureka,Gitlab为配置中心仓库

正文

在SpringCloud工程中,有些时候需要检查服务真正获取到的配置。因为代码仓库中的不一定是服务真实加载的。

1. 无加密

  1. 如果没有配置用户名密码,比较简单,直接访问即可,比如config server地址是http://127.0.0.1:8770,客户端服务是service-a,profile默认,即访问http://127.0.0.1:8770/service-a 即可获取。HTTP访问的格式如下(也是访问的优先级):

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

2. 有加密

配置了用户名和密码
config server的配置如下:

spring:
  application:
    name: config-server
  security:
    user:
      name: test # HTTP访问配置中心时的用户名和密码
      password: test-pwd
  cloud:
    config:
      server:
        git:
          uri: http://gitlab.test.com/config-server.git
          username: git-user  #仓库的用户名密码
          password: git-pwd
          default-label: dev

服务端的配置如下:

spring:
  application:
    name: service-a
  cloud:
    config:
      discovery:
        enabled: true 
        serviceId: config-server
      fail-fast: true
      username: test  # !!!这里和config server配置的一致
      password: test-pwd

这种加了密的访问方式有两种:

1. 通过URI的userInfo实现

这种适合知道用户名、密码的情况,使用方式,请求地址中加入用户名、密码,http://用户名:密码@ip:端口/服务名/xxxx,比如:
curl http://test:[email protected]:8770/service-a
实现代码解析(下面版本是SpringCloud 1.5.22源码):

org.springframework.cloud.config.client.ConfigServicePropertySourceLocator#getSecureRestTemplate
private RestTemplate getSecureRestTemplate(ConfigClientProperties client) {
		SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
		requestFactory.setReadTimeout((60 * 1000 * 3) + 5000); //TODO 3m5s, make configurable?
		RestTemplate template = new RestTemplate(requestFactory);
		# 这里就是重点
		String username = client.getUsername();
		String password = client.getPassword();
		String authorization = client.getAuthorization();
		Map headers = new HashMap<>(client.getHeaders());

		if (password != null && authorization != null) {
			throw new IllegalStateException(
					"You must set either 'password' or 'authorization'");
		}

		if (password != null) {
			byte[] token = Base64Utils.encode((username + ":" + password).getBytes());
			headers.put("Authorization", "Basic " + new String(token));
		}
		else if (authorization != null) {
			headers.put("Authorization", authorization);
		}

		if (!headers.isEmpty()) {
			template.setInterceptors(Arrays. asList(
					new GenericRequestHeaderInterceptor(headers)));
		}

		return template;
	}

org.springframework.cloud.config.client.ConfigClientProperties#extractCredentials
private Credentials extractCredentials() {
		Credentials result = new Credentials();
		String uri = this.uri;
		result.uri = uri;
		Credentials explicitCredentials = getUsernamePassword();
		result.username = explicitCredentials.username;
		result.password = explicitCredentials.password;
		try {
			URL url = new URL(uri);
			# 此处获取用户名、密码
			String userInfo = url.getUserInfo();
			// no credentials in url, return explicit credentials
			if (StringUtils.isEmpty(userInfo) || ":".equals(userInfo)) {
				return result;
			}
	}

2. 先Base65加密,请求时在Header中带上

如果无法知道用户名、密码,可以让运维人员提供token,生成token的代码样例就是上方第一个代码样例中的

byte[] token = Base64Utils.encode((username + ":" + password).getBytes());
headers.put("Authorization", "Basic " + new String(token));

请求中将header加入Authorization,值为Basic token的值,假如生成的token为xxxxxx,请求如下:
curl "http://127.0.0.1:8770/service-a" -H "Authorization: Basic xxxxxx"

你可能感兴趣的:(JAVA,spring,cloud,spring,后端)