1. 程式人生 > >SpringCloud-----Rest服務提供端【安全訪問】以及【消費端訪問】

SpringCloud-----Rest服務提供端【安全訪問】以及【消費端訪問】

1、服務提供端如果沒有安全訪問機制,會出現什麼問題?

把這些介面放在Internet伺服器上,無異於裸奔,所有資訊都容易被洩露;

任何使用者只要得到介面,那我們的程式將毫無祕密可言。

2、Spring-boot-security提供安全訪問機制

服務提供端匯入依賴包:

pom.xml

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

配置application.yml

#安全配置
security:
  basic:
    enabled: true #啟用SpringSecurity的安全配置
  user:
    name: wendy #認證使用者名稱
    password: wendy #認證密碼
    role:  #授權
    - USER

啟動程式,訪問結果如下:

輸入在application.yml中配置的username和password

3,服務消費端訪問服務端

服務消費端是公國RestTemplate的介面訪問服務提供端的,

而認證的使用者名稱和密碼服務端是通過請求的Header中獲取的,

所以我們需要在RestTemplate中設定Header資訊。設定如下:

RestConfig.java中新增HttpHeaders的配置bean

@Bean
	public HttpHeaders getHeaders(){
		// 進行一個Http頭資訊配置
		HttpHeaders headers = new HttpHeaders();
		String auth = "wendy:wendy";
		byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
		// 加密字串要有空格
		String authHeader = "Basic " + new String(encodedAuth);
		
		headers.set("Authorization", authHeader);
		return headers;
	}

DeptController.java

呼叫restTemplate的exchange來設定headers

package com.zemel.consumer.controller;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.zemel.vo.Dept;

@RestController
@RequestMapping("/consumer/dept")
public class DeptController {
	
	static final String DEPT_GET_URL = "http://dept-8001.com:8001/dept/get/";
	static final String DEPT_LIST_URL = "http://dept-8001.com:8001/dept/list/";
	static final String DEPT_ADD_URL = "http://dept-8001.com:8001/dept/add/";
	
	@Resource
	private RestTemplate restTemplate;
	
	@Resource
	private HttpHeaders headers;

	@GetMapping("/get")
	public Object getDept(long id){
		
		return this.restTemplate.exchange(DEPT_GET_URL+id, HttpMethod.GET, new HttpEntity(headers), Dept.class);
//		return this.restTemplate.getForEntity(DEPT_GET_URL+id, Dept.class);
	}
	
	@GetMapping("/list")
	public Object list(){
		return this.restTemplate.exchange(DEPT_LIST_URL, HttpMethod.GET, new HttpEntity(headers), List.class);
//		return this.restTemplate.getForObject(DEPT_LIST_URL, List.class);
	}
	
	@GetMapping("/add")
	public Object add(Dept dept){
		return this.restTemplate.exchange(DEPT_ADD_URL, HttpMethod.POST, new HttpEntity(dept,headers), Boolean.class);
//		return this.restTemplate.postForObject(DEPT_ADD_URL, dept, Boolean.class);
	}
}

注意:HttpHeaders的bean配置中,原理是往bean中新增Authorization屬性值

而Authorization的屬性值是通過如下的組成方式編譯的,

String auth = "wendy:wendy";
		byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
		
String authHeader = "Basic " + new String(encodedAuth);

以上程式碼是消費端訪問服務端的核心。

其中Basic後面要加一個空格,原來是去檢視Spring-security的原始碼,

會發現,Authorization資訊的解析原理就是如此。