本文是精講RestTemplate第9篇,前篇的blog訪問地址如下:
- 精講RestTemplate第1篇-在Spring或非Spring環境下如何使用
- 精講RestTemplate第2篇-多種底層HTTP客戶端類別庫的切換
- 精講RestTemplate第3篇-GET請求使用方法詳解
- 精講RestTemplate第4篇-POST請求方法使用詳解
- 精講RestTemplate第5篇-DELETE、PUT等請求方法使用詳解
- 精講RestTemplate第6篇-檔案上傳下載與大檔案流式下載
- 精講RestTemplate第7篇-自定義請求失敗例外處理
- 精講RestTemplate第8篇-請求失敗自動重試機制
服務提供方通常會通過一定的授權、鑒權認證邏輯來保護API介面,其中比較簡單、容易實作的方式就是使用HTTP 的Basic Auth來實作介面訪問用戶的認證,我們本節就來為大家介紹一下,在服務端加入Basic Auth認證的情況下,該如何使用RestTemplate訪問服務端介面,
一、HttpBasic認證原理說明

- 首先,HttpBasic模式要求傳輸的用戶名密碼使用Base64模式進行加密,如果用戶名是
"admin",密碼是“ admin”,則將字串"admin:admin"使用Base64編碼演算法加密,加密結果可能是:YWtaW46YWRtaW4=, - 然后,在Http請求中使用authorization作為一個HTTP請求頭Header name,“Basic YWtaW46YWRtaW4=“作為Header的值,發送給服務端,(注意這里使用Basic+空格+加密串)
- 服務器在收到這樣的請求時,到達BasicAuthenticationFilter過濾器,將提取“authorization”的Header值,并使用用于驗證用戶身份的相同演算法Base64進行解碼,
- 解碼結果與登錄驗證的用戶名密碼匹配,匹配成功則可以繼續過濾器后續的訪問,
二、HTTP Basic Auth服務端實作
如果你想自己搭建一個服務端,那么如何為Spring Boot 服務添加Basic Auth認證?請參考我的另外一篇文章:《Spring Security系列之Http Basic Auth登錄認證模式》 ,
當然我們也可以不用自己去搭建服務端,給大家介紹一個提供免費在線的RESTful介面服務的網站:httpbin.com,這個網站為我們提供了Basic Auth認證測驗服務介面,如果我們只是為了學習RestTemplate,直接用這個網站提供的服務就可以了,

瀏覽器訪問地址:http://www.httpbin.org/#/Auth/get_basic_auth__user___passwd_ ,這個介面服務是通過OpenAPI(swagger)實作的,所以可以進行在線的訪問測驗,所以可以先通過頁面操作測驗一下,再開始下面學習使用RestTemplate訪問服務端介面,
三、請求頭方式攜帶認證資訊
在HTTP請求頭中攜帶Basic Auth認證的用戶名和密碼,具體實作參考下文代碼注釋:
@SpringBootTest
class BasicAuthTests {
@Resource
private RestTemplate restTemplate;
@Test
void testBasicAuth() {
//該url上攜帶用戶名密碼是httpbin網站測驗介面的要求,
//真實的業務是不需要在url上體現basic auth用戶名密碼的
String url = "http://www.httpbin.org/basic-auth/admin/adminpwd";
//在請求頭資訊中攜帶Basic認證資訊(這里才是實際Basic認證傳遞用戶名密碼的方式)
HttpHeaders headers = new HttpHeaders();
headers.set("authorization",
"Basic " +
Base64.getEncoder()
.encodeToString("admin:adminpwd".getBytes()));
//發送請求
HttpEntity<String> ans = restTemplate
.exchange(url,
HttpMethod.GET, //GET請求
new HttpEntity<>(null, headers), //加入headers
String.class); //body回應資料接收型別
System.out.println(ans);
}
}
測驗用例執行成功,說明RestTemplate 正確的攜帶了Basic 認證資訊,得到正常的回應結果:200,

四、攔截器方式攜帶認證資訊
第三小節中的代碼雖然實作了功能,但是不夠好,因為每一次發送HTTP請求,我們都需要去組裝HttpHeaders 資訊,這樣不好,造成大量的代碼冗余,那么有沒有一種方式可以實作可以一次性的為所有RestTemplate請求API添加Http Basic認證資訊呢?答案就是:在RestTemplate Bean初始化的時候加入攔截器,以攔截器的方式統一添加Basic認證資訊,
下面的代碼結合注釋去看,如果看不懂,需要去參考:精講RestTemplate第2篇-多種底層HTTP客戶端類別庫的切換
@Configuration
public class ContextConfig {
@Bean("OKHttp3")
public RestTemplate OKHttp3RestTemplate(){
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
//添加攔截器
restTemplate.getInterceptors().add(getCustomInterceptor());
return restTemplate;
}
//實作一個攔截器:使用攔截器為每一個HTTP請求添加Basic Auth認證用戶名密碼資訊
private ClientHttpRequestInterceptor getCustomInterceptor(){
ClientHttpRequestInterceptor interceptor = (httpRequest, bytes, execution) -> {
httpRequest.getHeaders().set("authorization",
"Basic " +
Base64.getEncoder()
.encodeToString("admin:adminpwd".getBytes()));
return execution.execute(httpRequest, bytes);
};
return interceptor;
}
//這段代碼是《第3節-底層HTTP客戶端實作切換》的內容
private ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 100000;
OkHttp3ClientHttpRequestFactory clientHttpRequestFactory
= new OkHttp3ClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return clientHttpRequestFactory;
}
}
在RestTemplate Bean初始化的時候加入攔截器之后,第三小節中的代碼就可以省略HttpHeaders Basic Auth請求頭攜帶資訊的組裝程序,發送請求,結果和第三小節中的效果是一樣的,
五、進一步簡化
上面的方式使用了攔截器,但仍然是我們自己來封裝HTTP headers請求頭資訊,進一步的簡化方法就是,Spring RestTemplate 已經為我們提供了封裝好的Basic Auth攔截器,我們直接使用就可以了,不需要我們自己去實作攔截器,

下面的方法是在RestTemplate Bean實體化的時候使用RestTemplateBuilder,自帶basicAuthentication,所以到這里攔截器也不需要了(實際底層代碼實作仍然是攔截器,只是api層面不需要指定攔截器了),

發送請求,結果和第三小節中的效果是一樣的,
歡迎關注我的博客,里面有很多精品合集
- 本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客,
覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! ,另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注,
- 《手摸手教你學Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《實戰前后端分離RBAC權限管理系統》
- 《實戰SpringCloud微服務從青銅到王者》
- 《VUE深入淺出系列》
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/73360.html
標籤:Java
