摘要:在登錄后臺(tái)時(shí)也是必須認(rèn)證才行。使用這種總比粗暴的限制訪問來保護(hù)安全要高效的多,一切都是為了自動(dòng)化,為了提高生產(chǎn)率。總結(jié)本文主要學(xué)習(xí)使用這個(gè)神器來做,并學(xué)習(xí)了如何使用集成進(jìn)程序中。我司最近需要一名伙伴一起共同航海去,有興趣速來。
說明:本文主要研究利用Duo來實(shí)現(xiàn)雙重認(rèn)證,Two-Factor Authentication就是除了username-password這種登錄認(rèn)證之外,還使用第二層安全認(rèn)證,引用官網(wǎng)What is Two-Factor Authentication?的一句話:
A second layer of security to your login, in addition to your password.
這里,就是使用Duo來實(shí)現(xiàn)二次安全認(rèn)證,保護(hù)程序防止被惡意者登錄。需要實(shí)現(xiàn)二次登錄認(rèn)證的場(chǎng)景還是很多的,如登錄云服務(wù)器AWS或Aliyun時(shí)只是賬號(hào)密碼登錄是遠(yuǎn)遠(yuǎn)不夠,安全性較差,如果登錄AWS的private key被別人知道了,那惡意者也會(huì)登錄到你的AWS,那就麻煩了,代碼豈不暴露了;還有公司內(nèi)部的一些后臺(tái)網(wǎng)站,如果只是username-password這種基本認(rèn)證也遠(yuǎn)不夠安全,如果被別人知道了賬號(hào)密碼登陸進(jìn)去那就泄露了公司秘密了,限制IP登錄也挺麻煩的,那豈不是除了公司外其他地方不能訪問內(nèi)部網(wǎng)站了,如果想在家訪問一個(gè)業(yè)務(wù)的后臺(tái)就麻煩了。
使用Duo來做多一層保護(hù)會(huì)更安全,Duo的Web Application Protection工作原理如圖:
上圖描述的主要內(nèi)容就是除了輸入基本的賬號(hào)密碼認(rèn)證外,還得經(jīng)過Duo的二次認(rèn)證。如在我司在登錄AWS云時(shí),除了private key認(rèn)證外,還得必須經(jīng)過Duo安全認(rèn)證才能安全登錄AWS,Duo認(rèn)證選擇的方式是Mobile Push Notification,這樣當(dāng)有惡意者知道了個(gè)人的private key想要登錄AWS,個(gè)人的手機(jī)就會(huì)收到Duo Push Notification,只有個(gè)人在手機(jī)上選擇Approve才能登錄,而且也知道了private key被盜取了趕緊換一個(gè)key做補(bǔ)救措施。在登錄后臺(tái)時(shí)也是必須Duo認(rèn)證才行。實(shí)際上,Duo還能集成進(jìn)Github上,這樣登錄Github時(shí)也必須經(jīng)過Duo認(rèn)證,就算被知道了賬號(hào)密碼也不會(huì)被登錄個(gè)人的Github賬號(hào)。
這里主要學(xué)習(xí)下如何利用Duo來Protect Web Application,這里假設(shè)Web程序是Laravel寫的,看如何集成進(jìn)Laravel中實(shí)現(xiàn)二次認(rèn)證。假設(shè)由于業(yè)務(wù)需求,有一個(gè)后臺(tái)Admin,并是username-password這種HTTP Basic Authentication的(很多時(shí)候username-password認(rèn)證在公司內(nèi)都是SSO{Single Sign On},多個(gè)系統(tǒng)只需要一套u(yù)sername-password,這個(gè)可以使用Atlassian Crowd來做,以后再聊這個(gè)Crowd)。
開發(fā)環(huán)境:Laravel5.3 + PHP7
Duo Account進(jìn)去Duo官網(wǎng)注冊(cè)個(gè)賬號(hào)先,Duo Pricing對(duì)個(gè)人使用不超過10個(gè)用戶時(shí)是免費(fèi)的,其余套餐的價(jià)格也很便宜。然后在手機(jī)端下載個(gè)Duo應(yīng)用。最后使用Duo賬號(hào)登錄進(jìn)后臺(tái),后臺(tái)登錄使用Push認(rèn)證,這樣Duo Mobile App就會(huì)收到Push Notification,選擇Approve就會(huì)自動(dòng)登錄Duo 后臺(tái):
登錄后臺(tái),創(chuàng)建一個(gè)Application獲取keys,不同的Application有不同的keys,這樣可以不同的Admin后臺(tái)使用不同Application的keys,方便管理:
選擇Web SDK,因?yàn)楸疚氖菍W(xué)習(xí)使用Duo的SDK集成進(jìn)Admin后臺(tái),來保護(hù)后臺(tái)Admin程序:
這樣就得到了名叫Web SDK的Application了,并得到了對(duì)應(yīng)的Integration key,Secret key,API hostname這三個(gè)keys,后續(xù)集成SDK時(shí)需要這三個(gè)keys:
Two-Factor Authentication把Duo SDK集成進(jìn)Laravel中實(shí)際上就是多加一個(gè)Middleware,這里假設(shè)名為auth.duo,先做個(gè)中間件:
php artisan make:middleware DuoTwoFactorAuthentication
然后寫上中間件代碼,首先經(jīng)過username-password第一層認(rèn)證(這里假設(shè)是HTTP Basic Authentication),然后再是Duo Authentication第二層認(rèn)證,最后認(rèn)證通過再$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程序后臺(tái)路由是http://sentry.app:8888/duo(假設(shè)本地配置的host是sentry.app:8888),但需要經(jīng)過HTTP Basic Authentication這個(gè)第一層認(rèn)證,HTTP Basic Authentication就是根據(jù)輸入的username-password來查詢users表中有沒有對(duì)應(yīng)的user,這里先在users表中造一個(gè),使用Laravel自帶的Auth Scaffold,然后使用Register功能往users表中插入一個(gè)user,這樣也方便:
php artisan make:auth
然后輸入http://sentry.app:8888/register往users表插入一個(gè)username: [email protected],password: lx1036:
根據(jù)官方文檔Duo Web中說明,需要安裝一個(gè)package:
composer require duosecurity/duo_php
然后加上控制器TwoFactorAuthenticationController,這里需要向session中寫入$user_id,這里使用redis作為session驅(qū)動(dòng),記得修改.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這三個(gè)從Web SDK 這個(gè)Application中得到的keys,DUO_AKEY根據(jù)官方文檔是個(gè)人生成的,這里選擇Laravel的APP_KEY。
最后按照官方文檔的格式,把view頁(yè)面寫上:
// 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這個(gè)package里就有的,拷貝過來就行。
然后輸入路由http://sentry.app:8888/duo會(huì)彈出Basic Authentication Form,輸入剛剛注冊(cè)的[email protected],lx1036實(shí)現(xiàn)第一層認(rèn)證后,再根據(jù)中間件DuoTwoFactorAuthentication的return redirect()->guest("/2fa");邏輯就會(huì)跳轉(zhuǎn)到/2fa頁(yè)面實(shí)現(xiàn)第二層認(rèn)證:
選擇Send me a Push后,手機(jī)端Duo APP就會(huì)就會(huì)收到Push Notification了,當(dāng)然前提是手機(jī)端Duo已經(jīng)登錄了。選擇Approve后桌面端程序就自動(dòng)跳轉(zhuǎn)到路由http://sentry.app:8888/duo,這次走的中間件DuoTwoFactorAuthentication中邏輯是$request->session()->get(TwoFactorAuthenticationController::SESSION_KEY) == Auth::guard($guard)->user()->getAuthIdentifier(),這樣程序就經(jīng)過二次認(rèn)證了,程序就進(jìn)入登陸后的頁(yè)面,這里只是簡(jiǎn)單顯示Duo Authentication:
It is working.
有了Duo這個(gè)神器,就很安全的實(shí)現(xiàn)二次認(rèn)證了,這里是展示了如何使用Web SDK來保護(hù)Web Application,需要編碼,還可以在Duo后臺(tái)配置實(shí)現(xiàn)服務(wù)器登錄的二次認(rèn)證,這些就是配置下就行,不需要編碼,當(dāng)然Duo還有很多其他集成來實(shí)現(xiàn)二次保護(hù)。使用這種Modern Security Protection總比粗暴的限制IP訪問來保護(hù)安全要高效的多,一切都是為了自動(dòng)化,為了提高生產(chǎn)率。Duo已經(jīng)在我司RightCapital長(zhǎng)時(shí)間使用了,用起來還很順手,值得推薦下。
總結(jié):本文主要學(xué)習(xí)使用Duo這個(gè)神器來做Two Factor Authentication,并學(xué)習(xí)了如何使用Web SDK集成進(jìn)Laravel程序中。以后遇到好的技術(shù)再分享下,到時(shí)見。
我司最近需要一名伙伴一起共同航海去,有興趣速來Profile。
歡迎關(guān)注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/30498.html
摘要:中異常處理類主要包含兩個(gè)方法和,其中就是主要用來向第三方發(fā)送異常報(bào)告,這里選擇向這個(gè)神器發(fā)送異常報(bào)告,并使用通知開發(fā)人員。通過也能發(fā)現(xiàn)的執(zhí)行流程。 說明:Laravel學(xué)習(xí)筆記之bootstrap源碼解析中聊異常處理時(shí)提到過Sentry這個(gè)神器,并打算以后聊聊這款神器,本文主要就介紹這款Errors Tracking神器Sentry,Sentry官網(wǎng)有一句話個(gè)人覺得帥呆了: Stop ...
摘要:提供了一些函數(shù)處理操作的內(nèi)置函數(shù),主要有開發(fā)環(huán)境是調(diào)用回調(diào)函數(shù),并把一個(gè)數(shù)組作為參數(shù)傳進(jìn)去作為回調(diào)函數(shù)的參數(shù)也是調(diào)用回調(diào)函數(shù),區(qū)別是并沒有要求把數(shù)組作為參數(shù)傳進(jìn)回調(diào)函數(shù)做參數(shù)。 說明:Laravel中經(jīng)常使用PHP的Function Handling來設(shè)計(jì)代碼,本文主要學(xué)習(xí)PHP的Function Handling特性,來提高寫代碼時(shí)的設(shè)計(jì)質(zhì)量。PHP提供了一些函數(shù)處理操作的內(nèi)置函數(shù),...
摘要:看下兩個(gè)方法的源碼同樣是使用了對(duì)象來添加命令和。 說明:本文主要學(xué)習(xí)Schema Builder和Migration System的使用及相關(guān)原理。傳統(tǒng)上在設(shè)計(jì)database時(shí)需要寫大量的SQL語(yǔ)句,但Laravel提供了Schema Builder這個(gè)神器使得在設(shè)計(jì)database時(shí)使用面向?qū)ο蠓椒▉碜?,不需要寫一行SQL,并且還提供了另一個(gè)神器Migration System,可...
摘要:說明本文主要講述了的文件系統(tǒng)的小,邏輯不復(fù)雜,主要就是把上的一個(gè)文件下載到本地,和下載到中。寫驅(qū)動(dòng)由于沒有驅(qū)動(dòng),需要自定義下在中寫上名為的驅(qū)動(dòng)同時(shí)在注冊(cè)下該就行。執(zhí)行命令后,顯示上文件從上下載到上的文件該邏輯簡(jiǎn)單,但很好玩。 說明:本文主要講述了Laravel的文件系統(tǒng)Filesystem的小Demo,邏輯不復(fù)雜,主要就是把Dropbox上的一個(gè)文件下載到本地local,和下載到AWS...
摘要:總結(jié)本文主要學(xué)習(xí)了啟動(dòng)時(shí)做的七步準(zhǔn)備工作環(huán)境檢測(cè)配置加載日志配置異常處理注冊(cè)注冊(cè)啟動(dòng)。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動(dòng)Bootstrap工作,本文主要學(xué)習(xí)相關(guān)源碼,看看Laravel啟動(dòng)程序做了哪些具體工作,并將個(gè)人的研究心得分享出來,希望對(duì)別人有所幫助。Laravel在入口index...
閱讀 2438·2021-11-24 10:26
閱讀 2605·2021-11-16 11:44
閱讀 1725·2021-09-22 15:26
閱讀 3615·2021-09-10 11:11
閱讀 3215·2021-09-07 10:25
閱讀 3665·2021-09-01 10:41
閱讀 1042·2021-08-27 13:11
閱讀 3533·2021-08-16 11:02