﻿
{"id":20201,"date":"2020-12-26T01:20:29","date_gmt":"2020-12-26T01:20:29","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=20201"},"modified":"2020-12-26T01:20:29","modified_gmt":"2020-12-26T01:20:29","slug":"asp-net-core-5-0-angularda-jwt-esliginde-microsoftgoogle-authenticator-ile-two-factor-authentication","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-5-0-angularda-jwt-esliginde-microsoftgoogle-authenticator-ile-two-factor-authentication\/","title":{"rendered":"Asp.NET Core 5.0 &#8211; Angular&#8217;da JWT E\u015fli\u011finde Microsoft&#038;Google Authenticator \u0130le Two Factor Authentication"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Hat\u0131rlarsan\u0131z e\u011fer <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-two-factor-authentication-nedir\/\" rel=\"noopener noreferrer\" target=\"_blank\">Two Factor Authentication Nedir?<\/a> ba\u015fl\u0131kl\u0131 makalemizde Two Factor Authentication&#8217;\u0131n ne oldu\u011fundan bahsetmi\u015ftik ve <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-google-microsoft-authenticator-ile-two-factor-authentication\/\" rel=\"noopener noreferrer\" target=\"_blank\">Google &#038; Microsoft Authenticator \u0130le Two Factor Authentication<\/a> ba\u015fl\u0131kl\u0131 makalemizde ise Asp.NET Core MVC mimarisine \u00f6zel \u00e7ift a\u015famal\u0131 do\u011frulaman\u0131n nas\u0131l ger\u00e7ekle\u015ftirildi\u011fini ele alm\u0131\u015ft\u0131k. Bu i\u00e7eri\u011fimizde ise frontend&#8217;de bir SPA mimarisi olan Angular ile backend&#8217;de Asp.NET Core API&#8217;lar\u0131 t\u00fcketilirken bir yandan da Two Factor Authentication i\u015fleminin nas\u0131l ger\u00e7ekle\u015ftirildi\u011fini ele al\u0131yor olaca\u011f\u0131z.<\/p>\n<h3 style=\"color:#e83e8c;\">Ba\u015flarken<\/h3>\n<p>\u0130\u00e7eri\u011fimizin seyrine ba\u015flamadan \u00f6nce \u00fczerinde geli\u015ftirme yapabilmek i\u00e7in elinizde hali haz\u0131rda Angular ve Asp.NET Core Web API uygulamalar\u0131n\u0131n olmas\u0131 gerekmektedir. Bunun i\u00e7in sizlerin konuyu rahat takip edebilmesi ve herhangi bir kar\u0131\u015f\u0131kl\u0131l\u0131\u011fa mahal verilmemesi i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-3-1-ile-token-bazli-kimlik-dogrulamasi-ve-refresh-token-kullanimijwt\/\" rel=\"noopener noreferrer\" target=\"_blank\">JWT<\/a> konfig\u00fcrasyonuyla birlikte belli ba\u015fl\u0131 aksiyonlar\u0131 \u00f6nceden haz\u0131rlayarak olu\u015fturdu\u011fum Asp.NET Core 5.0 Web API ve Angular projelerini a\u015fa\u011f\u0131dan indirip ele al\u0131nacak olan konuya odakl\u0131 bir \u015fekilde \u00e7al\u0131\u015fman\u0131z\u0131 ger\u00e7ekle\u015ftirebilirsiniz.<\/p>\n<p>Sizlere \u00f6nceden haz\u0131rl\u0131k maksad\u0131yla sunulan bu projelerden Asp.NET Core uygulamas\u0131nda, kullan\u0131c\u0131 kayd\u0131yla birlikte JWT tabanl\u0131 kullan\u0131c\u0131 giri\u015fi deste\u011fi sa\u011flanmaktad\u0131r. Angular uygulamas\u0131nda ise gerekli i\u015flemlere e\u015flik edebilen component&#8217;lar tasarlanm\u0131\u015f ve guard yap\u0131s\u0131 ile API&#8217;dan gelen JWT&#8217;ye g\u00f6re UI tabanl\u0131 authorize i\u015flemleri sa\u011flanm\u0131\u015ft\u0131r. Tek yap\u0131lmas\u0131 gereken two factor authentication deste\u011finin sisteme entegre edilmesidir. Bunuda bu i\u00e7eri\u011fimizde birlikte ger\u00e7ekle\u015ftiriyor olaca\u011f\u0131z&#8230;<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/TwoFactorAuthenticationBackendExample.zip\">TwoFactorAuthenticationBackendExample<\/a><\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/TwoFactoryAuthenticationUIExample.zip\">TwoFactoryAuthenticationUIExample<\/a><\/p>\n<p>\u0130lgili projeleri indirdi\u011finizde Asp.NET Core uygulamas\u0131n\u0131n &#8216;Startup.cs&#8217; dosyas\u0131na g\u00f6z atarsan\u0131z e\u011fer;<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-300x227.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT \u0130le Birlikte Two Factor Authentication\" width=\"300\" height=\"227\" class=\"alignleft size-medium wp-image-20218\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-300x227.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-768x582.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication.png 935w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere gerekli context konfig\u00fcrasyonu e\u015fli\u011finde identity mekanizmas\u0131 entegre edilmi\u015ftir. Identity servisini g\u00f6rd\u00fc\u011f\u00fcn\u00fczde <strong><em>Hocam, hani JWT kullanacakt\u0131k?<\/em><\/strong> diye akl\u0131n\u0131zdan ge\u00e7ebilir. Lakin biz two factor authentication yapaca\u011f\u0131m\u0131zdan dolay\u0131 burada identity mekanizmas\u0131n\u0131n nimetlerinden faydalanaca\u011f\u0131z. O y\u00fczden altyap\u0131 olarak identity mekanizmas\u0131 kullan\u0131lmakta ve \u00f6zellikle kullan\u0131c\u0131 kay\u0131t ve giri\u015f i\u015flemleri i\u00e7in tercih edilmekte lakin kullan\u0131c\u0131 yetkilendirme i\u00e7in ise JWT kullan\u0131lmaktad\u0131r. Nihayetinde ilgili dosyada JWT konfig\u00fcrasyonununda yap\u0131ld\u0131\u011f\u0131 g\u00f6zlemlenebilmektedir. Yani uzun laf\u0131n k\u0131sas\u0131, JWT ile birlikte two factor authentication i\u015flemi yapabilmeniz i\u00e7in identity mekanizmas\u0131ndaki do\u011frulay\u0131c\u0131 metotlara ihtiya\u00e7 olaca\u011f\u0131ndan dolay\u0131 ilgili mimariyle i\u015flem yap\u0131lmas\u0131 gerekmektedir.<\/p>\n<p>Burada dikkat edilmesi gereken bir nokta mevcuttur. O da g\u00f6rselde vurguland\u0131\u011f\u0131 gibi &#8216;AddAuthentication&#8217; servisinde belirtilen \u015fema bildirileridir. E\u011fer ki, bir uygulamada JWT ve identity mekanizmalar\u0131n\u0131 bu \u015fekilde b\u00fct\u00fcnle\u015fik olarak kullanacaksan\u0131z kesinlikle ilgili \u015femalar\u0131n belirtilmesi zaruridir. Aksi taktirde s\u00fcre\u00e7te yetkilendirmeye dair baz\u0131 olas\u0131 hatalar s\u00f6z konusu olabilmektedir.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-1-300x168.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT \u0130le Birlikte Two Factor Authentication\" width=\"300\" height=\"168\" class=\"alignright size-medium wp-image-20222\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-1-300x168.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-1-768x431.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Ile-Birlikte-Two-Factor-Authentication-1.png 856w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Ayriyeten yine ayn\u0131 uygulama i\u00e7erisinde kullan\u0131c\u0131 kay\u0131t ve giri\u015f i\u015flemlerinden sorumlu olan &#8216;AuthController&#8217; isimli controller s\u0131n\u0131f\u0131ndaki &#8216;SignIn&#8217; fonksiyonuna g\u00f6z atarsan\u0131z e\u011fer \u015fifreyi do\u011frulamak ve giri\u015fi onaylamak i\u00e7in identity mekanizmas\u0131ndaki &#8216;SignInManager&#8217; class&#8217;\u0131 kullan\u0131lmaktad\u0131r. Bu onaydan sonra client&#8217;\u0131 yetkilendirmek i\u00e7in ise bir JWT \u00fcretilmektedir. <\/p>\n<h3 style=\"color:#e83e8c;\">Two Factor Authentication \u0130n\u015fas\u0131<\/h3>\n<p>Evet, art\u0131k ilgili projelerde two factor authentication in\u015fas\u0131na ba\u015flayabilliriz. Bunun i\u00e7in a\u015fa\u011f\u0131daki \u00f6nergeleri ad\u0131m ad\u0131m takip edebilirsiniz;<br \/>\n<strong><em>Angular Uygulamas\u0131nda Profil Sayfas\u0131n\u0131n D\u00fczenlenmesi<\/em><\/strong><br \/>\n\u0130lk olarak Angular uygulamas\u0131nda profil sayfas\u0131n\u0131n, kullan\u0131c\u0131n\u0131n iki a\u015famal\u0131 do\u011frulama se\u00e7ene\u011fini se\u00e7ebilece\u011fi \u015fekilde d\u00fczenlenmesi gerekmektedir.<br \/>\nprofile.component.html :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;div class=&quot;mb-3 form-check&quot;&gt;\r\n   &lt;input type=&quot;checkbox&quot; class=&quot;form-check-input&quot; &#x5B;(ngModel)]=&quot;cbTwoFactorAuth&quot;&gt;\r\n   &lt;label class=&quot;form-check-label&quot;&gt;Two Factor Authentication&lt;\/label&gt;\r\n&lt;\/div&gt;\r\n&lt;div class=&quot;mb-3&quot; *ngIf=&quot;cbTwoFactorAuth&quot;&gt;\r\n   &lt;label class=&quot;form-check-label&quot;&gt;\u00c7ift a\u015famal\u0131 do\u011frulama y\u00f6ntemini se\u00e7iniz.&lt;\/label&gt;&lt;br&gt;\r\n   &lt;select #selectAuth class=&quot;form-select&quot; (change)=&quot;changeAuthMethod()&quot; &#x5B;(ngModel)]=&quot;selectAuthMethod&quot;&gt;\r\n      &lt;option value=&quot;authenticator&quot;&gt;Authenticator&lt;\/option&gt;\r\n   &lt;\/select&gt;\r\n&lt;\/div&gt;\r\n \r\n&lt;div *ngIf=&quot;selectAuthMethod == 'authenticator' &amp;&amp; verificationCode &amp;&amp; cbTwoFactorAuth&quot;&gt;\r\n   &lt;div&gt;\r\n      &lt;qr-code &#x5B;value]=&quot;verificationCode.qrCodeUri&quot; &#x5B;size]=&quot;150&quot;&gt;&lt;\/qr-code&gt;\r\n   &lt;\/div&gt;\r\n   &lt;div class=&quot;mb-3&quot;&gt;\r\n      &lt;label class=&quot;form-label&quot;&gt;Do\u011frulama kodu&lt;\/label&gt;\r\n      &lt;input type=&quot;text&quot; class=&quot;form-control&quot; placeholder=&quot;Do\u011frulama kodu&quot; id=&quot;verificationCode&quot; &gt;\r\n   &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n \r\n&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot; (click)=&quot;Dogrula()&quot;&gt;Kaydet&lt;\/button&gt;\r\n<\/pre>\n<p>profile.component.ts :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { HttpHeaders } from '@angular\/common\/http';\r\nimport { Component, OnInit } from '@angular\/core';\r\nimport { VerificationCode } from 'src\/app\/entities\/verificationCode';\r\nimport { HttpService } from 'src\/app\/services\/http.service';\r\n\r\nimport * as $ from &quot;jquery&quot;;\r\n@Component({\r\n  selector: 'app-profile',\r\n  templateUrl: '.\/profile.component.html',\r\n  styleUrls: &#x5B;'.\/profile.component.css']\r\n})\r\nexport class ProfileComponent implements OnInit {\r\n\r\n  constructor(private httpService: HttpService) { }\r\n\r\n  cbTwoFactorAuth: boolean = false;\r\n  selectAuthMethod: any;\r\n  verificationCode: VerificationCode;\r\n\r\n  ngOnInit(): void { }\r\n\r\n  changeAuthMethod() {\r\n    if (this.selectAuthMethod == &quot;authenticator&quot;)\r\n      this.httpService.get(&quot;https:\/\/localhost:5001\/api\/auth\/getauthenticatorverifycode&quot;, new HttpHeaders({ &quot;Authorization&quot;: `Bearer ${localStorage.getItem(&quot;access_token&quot;)}` })).subscribe((codes: VerificationCode) =&gt; {\r\n        this.verificationCode = codes;\r\n      });\r\n  }\r\n\r\n  Dogrula() {\r\n    this.httpService.get(`https:\/\/localhost:5001\/api\/auth\/twofactorenable\/${this.cbTwoFactorAuth ? 1 : 0}\/${$(&quot;#verificationCode&quot;).val()}`, new HttpHeaders({ &quot;Authorization&quot;: `Bearer ${localStorage.getItem(&quot;access_token&quot;)}` }))\r\n      .subscribe((data: any) =&gt; {\r\n        alert(data.message);\r\n      });\r\n  }\r\n}\r\n<\/pre>\n<p>Yukar\u0131daki profile.component.ts dosyas\u0131na g\u00f6z atarsan\u0131z e\u011fer select listesinden se\u00e7ilen y\u00f6ntem e\u011fer &#8216;authenticator&#8217; de\u011ferine sahipse api&#8217;da ki <code>auth\/getauthenticatorverifycode<\/code> adresine bir istek g\u00f6ndermekte ve b\u00f6ylece authenticator do\u011frulama kodunu talep etmektedir.<\/p>\n<p>Backend&#8217;de ilgili kodu \u00fcretecek servisin i\u00e7eri\u011fi ise a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class AuthenticatorService\r\n    {\r\n        readonly UserManager&lt;AppUser&gt; _userManager;\r\n        readonly UrlEncoder _urlEncoder;\r\n        public AuthenticatorService(UserManager&lt;AppUser&gt; userManager, UrlEncoder urlEncoder)\r\n        {\r\n            _userManager = userManager;\r\n            _urlEncoder = urlEncoder;\r\n        }\r\n        public async Task&lt;string&gt; GenerateSharedKey(AppUser user)\r\n        {\r\n            string sharedKey = await _userManager.GetAuthenticatorKeyAsync(user);\r\n            if (string.IsNullOrEmpty(sharedKey))\r\n            {\r\n                IdentityResult result = await _userManager.ResetAuthenticatorKeyAsync(user);\r\n                if (result.Succeeded)\r\n                    sharedKey = await _userManager.GetAuthenticatorKeyAsync(user);\r\n            }\r\n            return sharedKey;\r\n        }\r\n        public async Task&lt;string&gt; GenerateQrCodeUri(string sharedKey, string title, AppUser user) =&gt;\r\n            $&quot;otpauth:\/\/totp\/{_urlEncoder.Encode(title)}:{_urlEncoder.Encode(user.Email)}?secret={sharedKey}&amp;issuer={_urlEncoder.Encode(title)}&quot;;\r\n    }\r\n<\/pre>\n<p>Ve bu servisi kullanarak do\u011frulama kodunun \u00fcretim talebini kar\u015f\u0131layacak olan &#8216;AuthController&#8217; i\u00e7erisindeki &#8216;GetAuthenticatorVerifyCode&#8217; isimli action\u0131n i\u00e7eri\u011fi ise;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        &#x5B;HttpGet(&quot;&#x5B;action]&quot;)]\r\n        &#x5B;Authorize]\r\n        public async Task&lt;IActionResult&gt; GetAuthenticatorVerifyCode()\r\n        {\r\n            AppUser user = await _userManager.FindByNameAsync(User.Identity.Name);\r\n            string sharedKey = await _authenticatorService.GenerateSharedKey(user);\r\n            string qrcodeUri = await _authenticatorService.GenerateQrCodeUri(sharedKey, &quot;Angular Two Factor Authentication Example&quot;, user);\r\n            return Ok(new\r\n            {\r\n                sharedKey = sharedKey,\r\n                qrCodeUri = qrcodeUri\r\n            });\r\n        }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-300x280.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"300\" height=\"280\" class=\"alignright size-medium wp-image-20236\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-300x280.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication.png 349w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>\u015feklinde olacakt\u0131r. Tabi burada ilgili action &#8216;Authorize&#8217; oldu\u011fu i\u00e7in token ile tetiklenmektedir ve i\u00e7erikteki koda bakarsan\u0131z <code>User.Identity.Name<\/code> komutu ile o anki yetkili kullan\u0131c\u0131n\u0131n ad\u0131na eri\u015filmeye \u00e7al\u0131\u015f\u0131lmaktad\u0131r. Burada ilgili datan\u0131n gelebilmesi i\u00e7in &#8216;Startup.cs&#8217; dosyas\u0131nda JWT servisinin eklendi\u011fi &#8216;AddJwtBearer&#8217; metodunda a\u015fa\u011f\u0131daki gibi &#8216;NameClaimType&#8217; de\u011ferinin verilmesi gerekmektedir. Bu \u00f6zellik, istekle birlikte gelen JWT&#8217;de ki &#8216;name&#8217; isimli claim&#8217;i almakta ve <code>User.Identity.Name<\/code> kodunda kullanmaktad\u0131r. Bu bilginin ard\u0131ndan akl\u0131n\u0131za <em>Peki kullan\u0131c\u0131ya \u00f6zel \u00fcretilen JWT&#8217;ye &#8216;name&#8217; claim&#8217;i nerede eklenmektedir?<\/em> gibisinden hakl\u0131 bir soru do\u011fabilir.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1-300x218.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"300\" height=\"218\" class=\"alignleft size-medium wp-image-20238\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1-300x218.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1.png 497w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Bu soru cevab\u0131n\u0131 esas\u0131nda kendi i\u00e7erisinde saklamaktad\u0131r. Yani JWT \u00fcretilirken eklenmektedir. Yandaki g\u00f6rseli incelerseniz e\u011fer JWT \u00fcretiminden sorumlu olan &#8216;TokenHandlerService&#8217; isimli servis \u00fcretilen token&#8217;a &#8216;name&#8217; claim&#8217;ini eklenmekte ve o \u015fekilde kullan\u0131c\u0131ya sunmaktad\u0131r. Konuyu daha iyi anlayabilmek i\u00e7in size \u00f6nceden sunmu\u015f oldu\u011fum proje i\u00e7erisinde gerekli g\u00f6zlemi yapabilir ve direkt olay\u0131 birincil g\u00f6zden kavrayabilirsiniz.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-2-259x300.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"259\" height=\"300\" class=\"alignright size-medium wp-image-20247\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-2-259x300.png 259w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-2.png 339w\" sizes=\"auto, (max-width: 259px) 100vw, 259px\" \/><\/a>Velhas\u0131l, yap\u0131lan bu \u00e7al\u0131\u015fma neticesinde kullan\u0131c\u0131 profil sayfas\u0131na gelerek, two factor authentication talebinde bulunur ve y\u00f6ntem olarak &#8216;Authenticator&#8217;\u0131 se\u00e7erse(ki \u00f6rne\u011fimizde ba\u015fka y\u00f6ntem bulunmamaktad\u0131r) yandaki gibi bir qrcode olu\u015fturulacak ve kullan\u0131c\u0131dan do\u011frulama beklenecektir. Do\u011frulama i\u015flemi i\u00e7in kayna\u011f\u0131 a\u015fa\u011f\u0131daki gibi olan <code>auth\/twofactorenable<\/code> adresi tetiklenmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        &#x5B;HttpGet(&quot;&#x5B;action]\/{state}\/{verificationCode}&quot;)]\r\n        &#x5B;Authorize]\r\n        public async Task&lt;object&gt; TwoFactorEnable(int state, string verificationCode)\r\n        {\r\n            bool result = false;\r\n            AppUser user = await _userManager.FindByNameAsync(User.Identity.Name);\r\n            if (state == 1)\r\n                result = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode);\r\n\r\n            if (!result &amp;&amp; state == 1)\r\n                return Ok(new\r\n                {\r\n                    State = false,\r\n                    Message = &quot;Do\u011frulama kodu hatal\u0131.&quot;\r\n                });\r\n\r\n            user.TwoFactorEnabled = (state == 1 ? true : false) &amp;&amp; result;\r\n            await _userManager.UpdateAsync(user);\r\n            await _userManager.UpdateSecurityStampAsync(user);\r\n\r\n            return Ok(new\r\n            {\r\n                State = user.TwoFactorEnabled,\r\n                Message = $&quot;\u00c7ift a\u015famal\u0131 do\u011frulama ba\u015far\u0131yla {(user.TwoFactorEnabled ? &quot;aktifle\u015ftirildi.&quot; : &quot;pasifle\u015ftirildi.&quot;)}&quot;\r\n            });\r\n        }\r\n<\/pre>\n<p>Burada &#8216;VerifyTwoFactorTokenAsync&#8217; metoduyla bir \u00e7ift a\u015famal\u0131 do\u011frulama token&#8217;\u0131 \u00fcretilece\u011finden dolay\u0131 &#8216;<em style=\"color:red;\">No IUserTwoFactorTokenProvider<TUser> named &#8216;Authenticator&#8217; is registered.<\/em>&#8216; hatas\u0131yla kar\u015f\u0131la\u015fmamak i\u00e7in &#8216;AddDefaultTokenProviders&#8217; servisini uygulamaya dahil etmeyi unutmay\u0131n\u0131z. Ayr\u0131ca yukar\u0131daki kodu incelerseniz e\u011fer girilen kodun do\u011fru olup olmad\u0131\u011f\u0131 denetlenmekte ve &#8216;state&#8217; de\u011ferine g\u00f6re two factor authentication&#8217;\u0131 aktif yahut pasif olarak d\u00fczenlemektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication.gif\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"800\" height=\"296\" class=\"aligncenter size-full wp-image-20264\" \/><\/a><br \/>\nKullan\u0131c\u0131 two factor authentication \u00f6zelli\u011fini aktifle\u015ftirdikten sonra kullan\u0131c\u0131 bilgileriyle tekrar oturum a\u00e7mak istedi\u011fi zaman yukar\u0131larda ele al\u0131nd\u0131\u011f\u0131 gibi SignInManager s\u0131n\u0131f\u0131n\u0131n &#8216;PasswordSignInAsync&#8217; metoduyla do\u011frulama yap\u0131lacak lakin &#8216;TwoFactorEnabled&#8217; kolonu true\/1 oldu\u011fu taktirde ikinci a\u015famal\u0131 do\u011frulamay\u0131 gerektirece\u011finden dolay\u0131 giri\u015fe izin vermeyecektir. Haliyle bu durumda client&#8217;\u0131 ikinci do\u011frulama a\u015famas\u0131n\u0131n gereksinimine dair bilgilendirmek gerekecektir. Dolay\u0131s\u0131yla bu i\u015flevsellik i\u00e7in backend&#8217;e gidip &#8216;SignIn&#8217; metodunu a\u015fa\u011f\u0131daki gibi g\u00fcncellememiz gerekecektir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-3.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"940\" height=\"606\" class=\"aligncenter size-full wp-image-20268\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-3.png 940w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-3-300x193.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-3-768x495.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/a>Bu de\u011fi\u015fiklik orjinali \u00fczerinde \u00e7ok spesifik oldu\u011fu i\u00e7in h\u0131zl\u0131ca yakalayabilmeniz i\u00e7in kod yerine g\u00f6rsel olarak vurgulamay\u0131 tercih ettim. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere &#8216;PasswordSignInAsync&#8217; kontrol\u00fc neticesinde bir ba\u015far\u0131s\u0131zl\u0131k varsa ve bu two factor authentication&#8217;dan kaynakl\u0131ysa client&#8217;a buna dair bir bilgilendirmede bulunmaktay\u0131z. Dolay\u0131s\u0131yla client edinece\u011fi bu bilgi sayesinde kullan\u0131c\u0131y\u0131 oturum a\u00e7ma esnas\u0131nda ikinci ad\u0131ma y\u00f6nlendirecektir.<\/p>\n<p>Angular uygulamas\u0131nda bu duruma istinaden gerekli aksiyon a\u015fa\u011f\u0131daki gibi al\u0131nabilir;<br \/>\nsignin.component.ts :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, OnInit } from '@angular\/core';\r\nimport { UserCreate } from 'src\/app\/entities\/userCreate';\r\nimport { UserLogin } from 'src\/app\/entities\/userLogin';\r\nimport { HttpService } from 'src\/app\/services\/http.service';\r\n\r\nimport * as $ from &quot;jquery&quot;;\r\nimport { Router } from '@angular\/router';\r\nimport { UserNameService } from 'src\/app\/services\/user-name.service';\r\n\r\n@Component({\r\n  selector: 'app-signin',\r\n  templateUrl: '.\/signin.component.html',\r\n  styleUrls: &#x5B;'.\/signin.component.css']\r\n})\r\nexport class SigninComponent implements OnInit {\r\n\r\n  constructor(private httpService: HttpService, private router: Router, private userNameService: UserNameService) { }\r\n\r\n  ngOnInit(): void {\r\n  }\r\n\r\n  signIn(userNameorEmail: HTMLInputElement, password: HTMLInputElement) {\r\n    const user: UserLogin = new UserLogin(userNameorEmail.value, password.value);\r\n    this.httpService.post(&quot;https:\/\/localhost:5001\/api\/auth\/signin&quot;, user).subscribe((data: any) =&gt; {\r\n      const message = $(&quot;#message&quot;);\r\n      message.addClass(&quot;alert-&quot; + (data.signInState == true ? &quot;success&quot; : &quot;danger&quot;));\r\n      message.html(data.signInState == true ? &quot;Giri\u015f ba\u015far\u0131l\u0131.&quot; : &quot;Kullan\u0131c\u0131 ad\u0131 veya \u015fifre hatal\u0131. L\u00fctfen tekrar deneyiniz.&quot;);\r\n      if (data.signInState) {\r\n        localStorage.setItem(&quot;access_token&quot;, data.token.accessToken);\r\n        localStorage.setItem(&quot;refresh_token&quot;, data.token.refreshToken);\r\n\r\n      } else if (data.requiresTwoFactor) {\r\n        \/\/Two Factor Authentication i\u00e7in ikinci a\u015famaya\/sayfaya y\u00f6nlendirme yap\u0131l\u0131yor...\r\n        this.userNameService.UserName = user.userNameOrEmail;\r\n        return this.router.navigateByUrl(&quot;sign-in-two-factor&quot;);\r\n      }\r\n\r\n      message.fadeIn(2000, () =&gt; {\r\n        setTimeout(() =&gt; {\r\n          message.fadeOut(2000, () =&gt; message.removeClass(&quot;alert-&quot; + (data.signInState == true ? &quot;success&quot; : &quot;danger&quot;)));\r\n        }, 2000);\r\n      });\r\n    });\r\n  }\r\n}\r\n<\/pre>\n<p>signin-two-factor.component.ts :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { HttpHeaders } from '@angular\/common\/http';\r\nimport { Component, OnInit } from '@angular\/core';\r\nimport { HttpService } from 'src\/app\/services\/http.service';\r\nimport { UserNameService } from 'src\/app\/services\/user-name.service';\r\n\r\n@Component({\r\n  selector: 'app-signin-two-factor',\r\n  templateUrl: '.\/signin-two-factor.component.html',\r\n  styleUrls: &#x5B;'.\/signin-two-factor.component.css']\r\n})\r\nexport class SigninTwoFactorComponent implements OnInit {\r\n\r\n  constructor(private httpService: HttpService, private userNameService: UserNameService) { }\r\n\r\n  ngOnInit(): void {\r\n  }\r\n  verify(verificationCode: string) {\r\n    this.httpService.post(&quot;https:\/\/localhost:5001\/api\/auth\/twofactorauthenticate&quot;, {\r\n      VerificationCode: verificationCode.toString(),\r\n      UsernameOrEmail: this.userNameService.UserName\r\n    })\r\n      .subscribe((data: any) =&gt; {\r\n        if (data.accessToken != null) {\r\n          localStorage.setItem(&quot;access_token&quot;, data.accessToken);\r\n          localStorage.setItem(&quot;refresh_token&quot;, data.refreshToken);\r\n        } else\r\n          alert(&quot;Do\u011frulama kodu hatal\u0131...&quot;);\r\n      });\r\n  }\r\n}\r\n<\/pre>\n<p>\u0130\u015fte bu kadar \ud83d\ude42 Art\u0131k uygulamalar\u0131 derleyip, \u00e7al\u0131\u015ft\u0131rabilir ve test edebiliriz.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-1.gif\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"800\" height=\"279\" class=\"aligncenter size-full wp-image-20274\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Angular&#8217;da Microsoft&#038;Google authenticator ile two factor authentication&#8217;\u0131 ba\u015far\u0131l\u0131 bir \u015fekilde uygulam\u0131\u015f olduk.<\/p>\n<p>Benim i\u00e7in san\u0131r\u0131m en zor ve anlat\u0131m\u0131 en kompleks i\u00e7eriklerden biri oldu diyebilirim \ud83d\ude42 Sabredip okudu\u011funuz i\u00e7in te\u015fekk\u00fcr ederim&#8230;<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek uygulamalar\u0131n son halini indirebilmek i\u00e7in a\u015fa\u011f\u0131daki adreslere t\u0131klay\u0131n\u0131z.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-4.png\" alt=\"Asp.NET Core 5.0 - Angular&#039;da JWT E\u015fli\u011finde Microsoft&amp;Google Authenticator \u0130le Two Factor Authentication\" width=\"847\" height=\"473\" class=\"aligncenter size-full wp-image-20278\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-4.png 847w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-4-300x168.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-5.0-Angularda-JWT-Esliginde-MicrosoftGoogle-Authenticator-Ile-Two-Factor-Authentication-4-768x429.png 768w\" sizes=\"auto, (max-width: 847px) 100vw, 847px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/TwoFactorAuthenticationBackendExample-1.zip\">TwoFactorAuthenticationBackendExample<\/a><\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/TwoFactoryAuthenticationUIExample-1.zip\">TwoFactoryAuthenticationUIExample<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Hat\u0131rlarsan\u0131z e\u011fer Two Factor Authentication Nedir? ba\u015fl\u0131kl\u0131 makalemizde Two Factor Authentication&#8217;\u0131n ne oldu\u011fundan bahsetmi\u015ftik ve Google &#038; Microsoft Authenticator \u0130le Two Factor Authentication ba\u015fl\u0131kl\u0131 makalemizde ise Asp.NET Core MVC mimarisine \u00f6zel \u00e7ift a\u015famal\u0131&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":20278,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,2420,3155,4026],"tags":[4028,4029,4031,4030,4027],"class_list":["post-20201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-angular","category-angular-9","category-asp-net-core-5-0","tag-angular-2fa","tag-angular-authenticator","tag-angular-google-authenticator","tag-angular-microsoft-authenticator","tag-angular-two-factor-authentication"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=20201"}],"version-history":[{"count":67,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20201\/revisions"}],"predecessor-version":[{"id":20281,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20201\/revisions\/20281"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/20278"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=20201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=20201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=20201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}