1、服务提供端如果没有安全访问机制,会出现什么问题?
把这些接口放在Internet服务器上,无异于裸奔,所有信息都容易被泄露;
任何用户只要得到接口,那我们的程序将毫无秘密可言。
2、Spring-boot-security提供安全访问机制
服务提供端导入依赖包:
pom.xml
org.springframework.boot
spring-boot-starter-security
2.1.0.RELEASE
配置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信息的解析原理就是如此。