身分驗證可以怎麼做?

近年來 Web 與相關技術進步,讓在此平台上的應用程式大放異彩,但同時對於身分驗證的安全要求也更加地嚴謹。

身分驗證會有下面三個必要的過程與注意事項,以下會一一說明。

  1. 註冊實體
  2. 身分驗證
  3. 狀態保存

註冊實體

註冊實體有三種方法:

  1. 線上註冊,在網路上透過完全公開的頁面或程式介面讓使用者註冊
  2. 私訊註冊,在網路上透過不公開的方法讓使用者註冊
  3. 線下註冊,不使用網路,而是在現實生活中註冊

以 Facebook 為例,在使用 Facebook 服務前,得先在網站提供的註冊(registration)表單輸入實體的唯一識別碼(identifier)--Email,也就是大家所熟悉的帳號,同時輸入一個只有自己才知道如何與此帳號綁定的方法--就是指密碼。

是的,「註冊實體」其實指的正是「註冊帳號」。

有的網站並不會讓使用者輸入帳號或密碼,而是另外用其他方法提供。比方說亂數產生,如十分鐘信箱,會直接產生一組臨時 Email 讓使用者直接使用。

除了使用網站公開的註冊表單以外,網站也可以使用不公開的註冊方法,如 Email 或其他通訊軟體等。還有一種方法是線下註冊,如由銀行開戶就是線下註冊,而要使用網銀轉帳時,就會綁定到線下註冊的實體。

註冊好實體,以及約定好綁定方法後,網站才有辦法在做身分驗證的時候,確認使用者與當初註冊的是同一個人。

風險

雖然不同的服務型態,會有不同的要求,如銀行的要求就特別多。而一般使用者透過網頁註冊的話,需要注意的安全如下:

  • TLS
  • XSS
  • CSP
  • CSRF
  • Same-origin Policy

TLS / CSP / CSRF / Same-origin Policy 的目的都是為了避免攻擊者竊取使用者的個資,而 CSRF 則是避免使用者被釣魚註冊成功。如果是 API 註冊(如 Dynamic Client Registration)的話,有 TLS 即可。

身分驗證

「我是誰?」正是身分驗證的目的,但在不同的場景會有不同的驗證方法。以 Facebook 為例,會有下列三種需要驗證的場景:

  1. 使用者想要使用 Facebook 提供的服務
  2. 第三方服務想呼叫 Facebook 提供的 API
  3. 第三方服務想利用 Facebook 的帳號來做身分驗證

第一種場景是最常看到的,使用者與 Facebook 服務的直接關係。當使用者要使用服務的時候,它就會跳出帳號密碼的輸入欄位來盤問(challenge)使用者,輸入帳密確認並綁定好實體後,Facebook 即可讓使用者透過實體的身分使用服務。

第二種場景則是第三方服務與 Facebook 串接的關係。這情境比較像「授權」,也就是誰授與第三方服務呼叫 Facebook API 的權限。

第三種場景則是使用者、第三方服務與 Facebook 的三角關係,第三方服務使用 Facebook 登入來當做自家的登入方法。這情境比較像「單一登入」,也就是只要 Facebook 登入過後,其他所有服務都能視為已登入。

未來將會繼續討論身分驗證的細節。

狀態保存

身分驗證完成後,因為 HTTP 是無狀態的,所以勢必會需要有狀態保存機制。若是使用者的話,可以使用 Cookie;第三方服務則會有更多元的保存方法。

風險

There are only two hard things in Computer Science: cache invalidation and naming things.

– Phil Karlton

「電腦科學領域中,最難的兩件事是:快取失效和命名」。狀態保存跟快取一樣都具有暫時性,因此最需要注意的重點是:如何清除狀態。

狀態保存方法有非常多種,但想清除的時候,真的能夠順利將該使用者的狀態全部清除嗎?會需要提醒這個問題的原因是:清除狀態的時機通常會是使用者請求或自行清除(如清 Cookie),但有時候會基於某些原因,會需要主動清除使用者的狀態。比方說,因為狀態有可能被竊取(如 Session Hijacking),那它就一定會發生(莫非定律),假設真的被竊取了,系統能做的事就是清除該攻擊者的狀態,讓風險不再擴大。而能不能控制風險,就看系統能不能主動清除使用者的狀態。

小結

今天討論了身分驗證所會經過的流程,事實上還有一些功能並不算在必要流程裡,如「忘記密碼」功能,這些額外的功能未來都有機會再討論。

參考資料