HttpClient 三種 Http Basic Authentication 認證方式,你瞭解了嗎?

Http Basic 簡介

HTTP 提供一個用於權限控制和認證的通用框架。最經常使用的 HTTP 認證方案是 HTTP Basic authentication。Http Basic 認證是一種用來容許網頁瀏覽器或其餘客戶端程序在請求時提供用戶名和口令形式的身份憑證的一種登陸驗證方式。java

優勢

  • 基本認證的一個優勢是基本上全部流行的網頁瀏覽器都支持基本認證。基本認證不多在可公開訪問的互聯網網站上使用,有時候會在小的私有系統中使用(如路由器網頁管理接口)。後來的機制HTTP摘要認證是爲替代基本認證而開發的,容許密鑰以相對安全的方式在不安全的通道上傳輸。
  • 程序員和系統管理員有時會在可信網絡環境中使用基本認證,使用Telnet或其餘明文網絡協議工具手動地測試Web服務器。這是一個麻煩的過程,可是網絡上傳輸的內容是人可讀的,以便進行診斷。

缺點

  • 雖然基本認證很是容易實現,但該方案建立在如下的假設的基礎上,即:客戶端和服務器主機之間的鏈接是安全可信的。特別是,若是沒有使用SSL/TLS這樣的傳輸層安全的協議,那麼以明文傳輸的密鑰和口令很容易被攔截。該方案也一樣沒有對服務器返回的信息提供保護。
  • 現存的瀏覽器保存認證信息直到標籤頁或瀏覽器被關閉,或者用戶清除歷史記錄。HTTP沒有爲服務器提供一種方法指示客戶端丟棄這些被緩存的密鑰。這意味着服務器端在用戶不關閉瀏覽器的狀況下,並無一種有效的方法來讓用戶註銷

上面是Http Basic的簡介,它不是咱們今天的主題,咱們今天的主題是:HttpClient 三種 Http Basic Authentication認證方式,是哪三種認證方式呢?接下來咱們去一探究竟,咱們從模擬 Http Basic 服務端開始。git

Http Basic 服務端

咱們使用 SpringBoot和Spring Security 簡單的搭建一個具備 HTTP Basic Authentication 的服務。具體的搭建過程我就不陳述了,我在這裏先貼出關鍵代碼,便於你的理解,完整的代碼已經上傳到GitHub上面,文章末尾有連接。程序員

配置 BasicAuthenticationEntryPoint

@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName());
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter printWriter = new PrintWriter(response.getOutputStream());
        printWriter.write("Http Status 401: " + authException.getLocalizedMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("developlee");
        super.afterPropertiesSet();
    }
}

配置 WebSecurityConfigurer

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyBasicAuthenticationEntryPoint authenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                // 開啓httpBasic
                .httpBasic()
                // 設置 BasicAuthenticationFilter
                .authenticationEntryPoint(authenticationEntryPoint);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("jamal").password(passwordEncoder().encode("123456")).authorities("ROLE_USER");
    }

    @Bean
    protected PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

編寫 Controller

@RestController
public class WebController {

    @RequestMapping(path = "/hello")
    public String hello(){
        return "驗證經過";
    }
}

啓動項目,訪問 http://127.0.0.1:8080/hellogithub


至此,咱們的 Http Basic 服務端搭建便已經完成了spring

HttpClient 三種 Http Basic 驗證方式

標準模式

private String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://127.0.0.1:8080/hello";

private String DEFAULT_USER = "jamal";

private String DEFAULT_PASS = "123456";

@Test
public void CredentialsProvider()throws Exception{
    // 建立用戶信息
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials credentials
            = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS);
    provider.setCredentials(AuthScope.ANY, credentials);

    // 建立客戶端的時候進行身份驗證
    HttpClient client = HttpClientBuilder.create()
            .setDefaultCredentialsProvider(provider)
            .build();

    HttpResponse response = client.execute(
            new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION));
    int statusCode = response.getStatusLine()
            .getStatusCode();
    Assert.assertEquals(statusCode,200);
}

搶先模式

@Test
public void PreemptiveBasicAuthentication()throws Exception{
    // 先進行身份驗證
    HttpHost targetHost = new HttpHost("localhost", 8080, "http");
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS));

    AuthCache authCache = new BasicAuthCache();
    // 將身份驗證放入緩存中
    authCache.put(targetHost, new BasicScheme());

    HttpClientContext context = HttpClientContext.create();
    context.setCredentialsProvider(credsProvider);
    context.setAuthCache(authCache);
    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(
            new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION), context);

    int statusCode = response.getStatusLine().getStatusCode();
    Assert.assertEquals(statusCode,200);
}

原生 Http Basic 模式

@Test
public void HttpBasicAuth()throws Exception{
    HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
    // 手動構建驗證信息
    String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
    byte[] encodedAuth = Base64.encodeBase64(
            auth.getBytes(StandardCharsets.UTF_8));
    String authHeader = "Basic " + new String(encodedAuth);
    // 將驗證信息放入到 Header
    request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(request);

    int statusCode = response.getStatusLine().getStatusCode();
    Assert.assertEquals(statusCode,200);
}

以上就是 HttpClient Http Basic 的三種驗證方式,但願對你有所幫助。瀏覽器

文章不足之處,望你們多多指點,共同窗習,共同進步
源代碼 點擊此處

最後

打個小廣告,歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,一塊兒進步吧。
平頭哥的技術博文緩存