摘要:在登錄后臺時也是必須認證才行。使用這種總比粗暴的限制訪問來保護安全要高效的多,一切都是為了自動化,為了提高生產率。總結本文主要學習使用這個神器來做,并學習了如何使用集成進程序中。我司最近需要一名伙伴一起共同航海去,有興趣速來。
說明:本文主要研究利用Duo來實現雙重認證,Two-Factor Authentication就是除了username-password這種登錄認證之外,還使用第二層安全認證,引用官網What is Two-Factor Authentication?的一句話:
A second layer of security to your login, in addition to your password.
這里,就是使用Duo來實現二次安全認證,保護程序防止被惡意者登錄。需要實現二次登錄認證的場景還是很多的,如登錄云服務器AWS或Aliyun時只是賬號密碼登錄是遠遠不夠,安全性較差,如果登錄AWS的private key被別人知道了,那惡意者也會登錄到你的AWS,那就麻煩了,代碼豈不暴露了;還有公司內部的一些后臺網站,如果只是username-password這種基本認證也遠不夠安全,如果被別人知道了賬號密碼登陸進去那就泄露了公司秘密了,限制IP登錄也挺麻煩的,那豈不是除了公司外其他地方不能訪問內部網站了,如果想在家訪問一個業務的后臺就麻煩了。
使用Duo來做多一層保護會更安全,Duo的Web Application Protection工作原理如圖:
上圖描述的主要內容就是除了輸入基本的賬號密碼認證外,還得經過Duo的二次認證。如在我司在登錄AWS云時,除了private key認證外,還得必須經過Duo安全認證才能安全登錄AWS,Duo認證選擇的方式是Mobile Push Notification,這樣當有惡意者知道了個人的private key想要登錄AWS,個人的手機就會收到Duo Push Notification,只有個人在手機上選擇Approve才能登錄,而且也知道了private key被盜取了趕緊換一個key做補救措施。在登錄后臺時也是必須Duo認證才行。實際上,Duo還能集成進Github上,這樣登錄Github時也必須經過Duo認證,就算被知道了賬號密碼也不會被登錄個人的Github賬號。
這里主要學習下如何利用Duo來Protect Web Application,這里假設Web程序是Laravel寫的,看如何集成進Laravel中實現二次認證。假設由于業務需求,有一個后臺Admin,并是username-password這種HTTP Basic Authentication的(很多時候username-password認證在公司內都是SSO{Single Sign On},多個系統只需要一套username-password,這個可以使用Atlassian Crowd來做,以后再聊這個Crowd)。
開發環境:Laravel5.3 + PHP7
Duo Account進去Duo官網注冊個賬號先,Duo Pricing對個人使用不超過10個用戶時是免費的,其余套餐的價格也很便宜。然后在手機端下載個Duo應用。最后使用Duo賬號登錄進后臺,后臺登錄使用Push認證,這樣Duo Mobile App就會收到Push Notification,選擇Approve就會自動登錄Duo 后臺:
登錄后臺,創建一個Application獲取keys,不同的Application有不同的keys,這樣可以不同的Admin后臺使用不同Application的keys,方便管理:
選擇Web SDK,因為本文是學習使用Duo的SDK集成進Admin后臺,來保護后臺Admin程序:
這樣就得到了名叫Web SDK的Application了,并得到了對應的Integration key,Secret key,API hostname這三個keys,后續集成SDK時需要這三個keys:
Two-Factor Authentication把Duo SDK集成進Laravel中實際上就是多加一個Middleware,這里假設名為auth.duo,先做個中間件:
php artisan make:middleware DuoTwoFactorAuthentication
然后寫上中間件代碼,首先經過username-password第一層認證(這里假設是HTTP Basic Authentication),然后再是Duo Authentication第二層認證,最后認證通過再$next($request):
guest()) { // Basic authentication is not set. return response("Unauthorized.", Response::HTTP_UNAUTHORIZED); } elseif ($request->session()->get(TwoFactorAuthenticationController::SESSION_KEY) == Auth::guard($guard)->user()->getAuthIdentifier()) { return $next($request); } else { // Duo Authentication // Basic authentication is set, but the duo middleware is not set. return redirect()->guest("/2fa"); } } }
并在AppHttpKernel中加上auth.duo:
protected $routeMiddleware = [ "auth" => IlluminateAuthMiddlewareAuthenticate::class, "auth.basic" => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class, "auth.crowd" => MiddlewareCrowdAuthentication::class, "auth.duo" => MiddlewareDuoTwoFactorAuthentication::class, "bindings" => IlluminateRoutingMiddlewareSubstituteBindings::class, "can" => IlluminateAuthMiddlewareAuthorize::class, "guest" => MiddlewareRedirectIfAuthenticated::class, "throttle" => IlluminateRoutingMiddlewareThrottleRequests::class, ];
然后寫上路由就行web.php,這里是使用auth.basicLaravel自帶的HTTP Basic Authentication(使用Crowd SSO登錄以后再聊):
//Route::group(["middleware" => "auth.crowd"], function () { Route::group(["middleware" => "auth.basic"], function () { Route::get("/2fa", "TwoFactorAuthenticationController@get"); Route::post("/2fa", "TwoFactorAuthenticationController@post"); Route::group(["middleware" => "auth.duo"], function () { Route::get("/duo", function () { return "Duo Authentication"; }); }); Route::get("/duo/users", function () { return view("users"); }); Route::get("/duo/accounts", function () { return view("accounts"); }); // and so on });
這樣Admin程序后臺路由是http://sentry.app:8888/duo(假設本地配置的host是sentry.app:8888),但需要經過HTTP Basic Authentication這個第一層認證,HTTP Basic Authentication就是根據輸入的username-password來查詢users表中有沒有對應的user,這里先在users表中造一個,使用Laravel自帶的Auth Scaffold,然后使用Register功能往users表中插入一個user,這樣也方便:
php artisan make:auth
然后輸入http://sentry.app:8888/register往users表插入一個username: user@example.com,password: lx1036:
根據官方文檔Duo Web中說明,需要安裝一個package:
composer require duosecurity/duo_php
然后加上控制器TwoFactorAuthenticationController,這里需要向session中寫入$user_id,這里使用redis作為session驅動,記得修改.env中SESSION_DRIVER=redis:
php artisan make:controller TwoFactorAuthenticationController config("services.duo.host"), "sig_request" => Web::signRequest( config("services.duo.integration_key"), config("services.duo.secret_key"), config("services.duo.application_key"), Auth::user()->getAuthIdentifier() ), "post_action" => url("2fa"), ]); } public function post(Request $request) { $user_id = Web::verifyResponse( config("services.duo.integration_key"), config("services.duo.secret_key"), config("services.duo.application_key"), $request->input("sig_response") ); if ($user_id == Auth::user()->getAuthIdentifier()) { $request->session()->put(self::SESSION_KEY, $user_id); return redirect()->intended("/duo"); } else { abort(Response::HTTP_UNAUTHORIZED); } } } // config/services.php "duo" => [ "host" => env("DUO_HOST"), "integration_key" => env("DUO_IKEY"), "secret_key" => env("DUO_SKEY"), "application_key" => env("DUO_AKEY"), ],
記得在.env文件中寫入DUO_HOST,DUO_IKEY,DUO_SKEY這三個從Web SDK 這個Application中得到的keys,DUO_AKEY根據官方文檔是個人生成的,這里選擇Laravel的APP_KEY。
最后按照官方文檔的格式,把view頁面寫上:
// resources/views/duo/2fa.blade.php @extends("layouts.duo") @section("content")@stop @section("js") @endsection // resources/views/layouts/duo.blade.phpTwo Factor Authentication
Duo: Two Factor Authentication @yield("js") // public/css/duo/duo.css #duo_iframe { width: 100%; min-width: 304px; max-width: 620px; height: 330px; } #duo { align-content: center; margin: auto; }@yield("content")
其中,Duo-Web-v2.min.js是duosecurity/duo_php這個package里就有的,拷貝過來就行。
然后輸入路由http://sentry.app:8888/duo會彈出Basic Authentication Form,輸入剛剛注冊的user@example.com,lx1036實現第一層認證后,再根據中間件DuoTwoFactorAuthentication的return redirect()->guest("/2fa");邏輯就會跳轉到/2fa頁面實現第二層認證:
選擇Send me a Push后,手機端Duo APP就會就會收到Push Notification了,當然前提是手機端Duo已經登錄了。選擇Approve后桌面端程序就自動跳轉到路由http://sentry.app:8888/duo,這次走的中間件DuoTwoFactorAuthentication中邏輯是$request->session()->get(TwoFactorAuthenticationController::SESSION_KEY) == Auth::guard($guard)->user()->getAuthIdentifier(),這樣程序就經過二次認證了,程序就進入登陸后的頁面,這里只是簡單顯示Duo Authentication:
It is working.
有了Duo這個神器,就很安全的實現二次認證了,這里是展示了如何使用Web SDK來保護Web Application,需要編碼,還可以在Duo后臺配置實現服務器登錄的二次認證,這些就是配置下就行,不需要編碼,當然Duo還有很多其他集成來實現二次保護。使用這種Modern Security Protection總比粗暴的限制IP訪問來保護安全要高效的多,一切都是為了自動化,為了提高生產率。Duo已經在我司RightCapital長時間使用了,用起來還很順手,值得推薦下。
總結:本文主要學習使用Duo這個神器來做Two Factor Authentication,并學習了如何使用Web SDK集成進Laravel程序中。以后遇到好的技術再分享下,到時見。
我司最近需要一名伙伴一起共同航海去,有興趣速來Profile。
歡迎關注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30498.html
摘要:中異常處理類主要包含兩個方法和,其中就是主要用來向第三方發送異常報告,這里選擇向這個神器發送異常報告,并使用通知開發人員。通過也能發現的執行流程。 說明:Laravel學習筆記之bootstrap源碼解析中聊異常處理時提到過Sentry這個神器,并打算以后聊聊這款神器,本文主要就介紹這款Errors Tracking神器Sentry,Sentry官網有一句話個人覺得帥呆了: Stop ...
摘要:提供了一些函數處理操作的內置函數,主要有開發環境是調用回調函數,并把一個數組作為參數傳進去作為回調函數的參數也是調用回調函數,區別是并沒有要求把數組作為參數傳進回調函數做參數。 說明:Laravel中經常使用PHP的Function Handling來設計代碼,本文主要學習PHP的Function Handling特性,來提高寫代碼時的設計質量。PHP提供了一些函數處理操作的內置函數,...
摘要:看下兩個方法的源碼同樣是使用了對象來添加命令和。 說明:本文主要學習Schema Builder和Migration System的使用及相關原理。傳統上在設計database時需要寫大量的SQL語句,但Laravel提供了Schema Builder這個神器使得在設計database時使用面向對象方法來做,不需要寫一行SQL,并且還提供了另一個神器Migration System,可...
摘要:說明本文主要講述了的文件系統的小,邏輯不復雜,主要就是把上的一個文件下載到本地,和下載到中。寫驅動由于沒有驅動,需要自定義下在中寫上名為的驅動同時在注冊下該就行。執行命令后,顯示上文件從上下載到上的文件該邏輯簡單,但很好玩。 說明:本文主要講述了Laravel的文件系統Filesystem的小Demo,邏輯不復雜,主要就是把Dropbox上的一個文件下載到本地local,和下載到AWS...
摘要:總結本文主要學習了啟動時做的七步準備工作環境檢測配置加載日志配置異常處理注冊注冊啟動。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動Bootstrap工作,本文主要學習相關源碼,看看Laravel啟動程序做了哪些具體工作,并將個人的研究心得分享出來,希望對別人有所幫助。Laravel在入口index...
閱讀 2373·2021-11-24 10:26
閱讀 2565·2021-11-16 11:44
閱讀 1695·2021-09-22 15:26
閱讀 3565·2021-09-10 11:11
閱讀 3178·2021-09-07 10:25
閱讀 3615·2021-09-01 10:41
閱讀 1002·2021-08-27 13:11
閱讀 3498·2021-08-16 11:02