您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java中怎么為WEB應用程序啟用兩步驗證”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Java中怎么為WEB應用程序啟用兩步驗證”文章能幫助大家解決問題。
支持雙因素身份驗證 (2FA) 幾乎總是一個好主意,尤其是對于后臺系統。2FA 有許多不同的形式,其中一些包括 SMS、TOTP 甚至硬件令牌。
啟用它們需要類似的流程:
用戶轉到他們的個人資料頁面(如果您想在注冊時強制使用 2fa,請跳過此頁面)
單擊“啟用雙因素身份驗證”
輸入一些數據以啟用特定的 2FA 方法(電話號碼、TOTP 驗證碼等)
下次登錄時,除了用戶名和密碼外,登錄表單還會請求第二個因素(驗證碼)并將其與憑據一起發送
我將重點介紹 Google Authenticator,它使用 TOTP(基于時間的一次性密碼)來生成一系列驗證碼。這個想法是服務器和客戶端應用程序共享一個密鑰。根據該鍵和當前時間,兩者都得出相同的代碼。當然,時鐘不是完全同步的,所以有一些代碼窗口被服務器接受為有效的。請注意,如果您不信任 Google 的應用程序,您可以使用下面的相同庫實現您自己的客戶端應用程序。
如何使用 Java(在服務器上)實現它?使用GoogleAuth
庫。流程如下:
用戶轉到他們的個人資料頁面
單擊“啟用雙因素身份驗證”
服務器生成一個密鑰,將其存儲為用戶配置文件的一部分,并將 URL 返回到二維碼。請注意,最好對機密進行加密,以使其更難被數據泄露破壞。
用戶使用他們的 Google Authenticator 應用程序掃描二維碼,從而在應用程序中創建一個新的個人資料
用戶在與二維碼一起出現的字段中輸入應用顯示的驗證碼,然后點擊“確認”
服務器在用戶配置文件中將 2FA 標記為已啟用
或者,您可以給用戶一些“臨時代碼”,他們可以寫下這些代碼,以防他們丟失應用程序或機密。
如果用戶不掃描代碼或不驗證過程,用戶配置文件將只包含一個孤立的密鑰,但不會被標記為已啟用
應該有一個選項可以稍后從他們的用戶個人資料頁面禁用 2FA
從理論的角度來看,這里最重要的一點是密鑰的共享。加密是對稱的,因此雙方(身份驗證器應用程序和服務器)具有相同的密鑰。它通過用戶掃描的二維碼共享。如果攻擊者在那時控制了用戶的機器,則機密可能會泄露,因此 2FA 也會被攻擊者濫用。但這不在威脅模型中——換句話說,如果攻擊者可以訪問用戶的機器,那么損害就已經造成了。
注意:您可能會看到此過程稱為 2 步身份驗證或 2 因素。“因素”是:“你知道的東西”、“你擁有的東西”和“你是的東西”。您可以將 TOTP 視為“您知道”的另一件事,但您也可以將帶有安全存儲的密鑰的手機視為“您擁有”的東西。在這種特殊情況下,我不堅持使用任何一個術語。
登錄后,流程如下:
用戶輸入用戶名和密碼,點擊“登錄”
頁面使用 AJAX 請求詢問服務器此電子郵件是否啟用了 2FA
如果未啟用 2FA,只需提交用戶名和密碼表格
如果啟用了 2FA,則不會提交登錄表單,而是會顯示一個附加字段,讓用戶從身份驗證器應用程序輸入驗證碼
用戶輸入代碼并按登錄后,即可提交表單。使用相同的登錄按鈕,或新的“驗證”按鈕,或者驗證輸入 + 按鈕可以是一個全新的屏幕(隱藏用戶名/密碼輸入)。
然后服務器再次檢查用戶是否啟用了 2FA,如果是,則驗證驗證碼。如果匹配,則登錄成功。如果不是,則登錄失敗,并且允許用戶重新輸入憑據和驗證碼。請注意,根據用戶名/密碼是否錯誤或代碼錯誤,您可以有不同的響應。您也可以在顯示驗證碼輸入之前嘗試登錄。這種方式可以說更好,因為這樣您就不會向潛在攻擊者透露用戶使用 2FA。
雖然我說的是用戶名和密碼,但它可以適用于任何其他身份驗證方法。從 OAuth/OpenID Connect/SAML
提供程序獲得成功確認后,或者在獲得來自SecureLogin
的令牌后,您可以請求第二個因素(代碼)。
在代碼中,上述流程如下所示(使用 Spring MVC;為了簡潔起見,我合并了控制器和服務層。您可以將 @AuthenticatedPrincipal
位替換為您將當前登錄的用戶詳細信息提供給控制器的方式)。假設方法在映射到“/user/”的控制器中:
@RequestMapping(value ="/init2fa", method = RequestMethod.POST)
@ResponseBody
public String initTwoFactorAuth(@AuthenticationPrincipal LoginAuthenticationToken token) {
User user = getLoggedInUser(token);
GoogleAuthenticatorKey googleAuthenticatorKey = googleAuthenticator.createCredentials();
// note - preferably encrypt it with an externally stored (or even HSM) key
user.setTwoFactorAuthKey(googleAuthenticatorKey.getKey());
dao.update(user);
return GoogleAuthenticatorQRGenerator.getOtpAuthURL(GOOGLE_AUTH_ISSUER, email, googleAuthenticatorKey);
}
@RequestMapping(value ="/confirm2fa", method = RequestMethod.POST)
@ResponseBody
public boolean confirmTwoFactorAuth(@AuthenticationPrincipal LoginAuthenticationToken token,@RequestParam("code")int code) {
User user = getLoggedInUser(token);
boolean result = googleAuthenticator.authorize(user.getTwoFactorAuthKey(), code);
user.setTwoFactorAuthEnabled(result);
dao.update(user);
return result;
}
@RequestMapping(value ="/disable2fa", method = RequestMethod.GET)
@ResponseBody
public void disableTwoFactorAuth(@AuthenticationPrincipal LoginAuthenticationToken token) {
User user = getLoggedInUser(token);
user.setTwoFactorAuthKey(null);
user.setTwoFactorAuthEnabled(false);
dao.update(user);
}
@RequestMapping(value ="/requires2fa", method = RequestMethod.POST)
@ResponseBody
public boolean login(@RequestParam("email") String email) {
// TODO consider verifying the password here in order not to reveal that a given user uses 2FA
return userService.getUserDetailsByEmail(email).isTwoFactorAuthEnabled();
}
二維碼生成使用 Google 的服務,從技術上講,該服務也為 Google 提供了密鑰。我懷疑他們除了生成二維碼之外還存儲它,但是如果您不信任他們,您可以實現自己的二維碼生成器,自己生成二維碼應該不難。
在客戶端,它是對上述方法的簡單 AJAX 請求(旁注:我有點覺得 AJAX 一詞不再流行,但我不知道如何調用它們。異步?背景?Javascript?)。
$("#two-fa-init").click(function() {
$.post("/user/init2fa",function(qrImage) {
$("#two-fa-verification").show();
$("#two-fa-qr").prepend($('<img>',{id:'qr',src:qrImage}));
$("#two-fa-init").hide();
});
});
$("#two-fa-confirm").click(function() {
var verificationCode = $("#verificationCode").val().replace(/ /g,'')
$.post("/user/confirm2fa?code=" + verificationCode,function() {
$("#two-fa-verification").hide();
$("#two-fa-qr").hide();
$.notify("Successfully enabled two-factor authentication","success");
$("#two-fa-message").html("Successfully enabled");
});
});
$("#two-fa-disable").click(function() {
$.post("/user/disable2fa",function(qrImage) {
window.location.reload();
});
});
登錄表單代碼在很大程度上取決于您正在使用的現有登錄表單,但重點是使用電子郵件(和密碼)調用 /requires2fa 以檢查是否啟用了 2FA,然后顯示驗證碼輸入。
總的來說,如果雙因素身份驗證的實現很簡單,我建議將它用于大多數系統,在這些系統中,安全性比用戶體驗的簡單性更重要。
關于“Java中怎么為WEB應用程序啟用兩步驗證”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。