﻿
{"id":28401,"date":"2026-02-12T07:01:38","date_gmt":"2026-02-12T07:01:38","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=28401"},"modified":"2026-02-12T07:01:38","modified_gmt":"2026-02-12T07:01:38","slug":"keycloak-asp-net-core-ile-browser-flow-authentication-7","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/","title":{"rendered":"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<br \/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_80 counter-hierarchy ez-toc-counter ez-toc-light-blue ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Ba\u015fl\u0131klar<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"\u0130\u00e7indekiler Tablosunu A\u00e7\/Kapat\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#Browser_Flow_Authentication_Nedir\" >Browser Flow Authentication Nedir?<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#Single_Sign-On_SSO_nasil_calisir\" >Single Sign-On (SSO) nas\u0131l \u00e7al\u0131\u015f\u0131r?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#SSOnun_avantajlari_ve_dezavantajlari_nelerdir\" >SSO&#8217;nun avantajlar\u0131 ve dezavantajlar\u0131 nelerdir?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#Browser_Flow_Ic_Yapisi\" >Browser Flow \u0130\u00e7 Yap\u0131s\u0131<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#6_Kritik_Soru_6_Kritik_Cevap\" >6 Kritik Soru \/ 6 Kritik Cevap<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#AspNET_Core_Keycloak_Browser_Flow_Ornek_Uygulama\" >Asp.NET Core | Keycloak | Browser Flow \u00d6rnek Uygulama<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#Login_Ekranini_Ozellestirme\" >Login Ekran\u0131n\u0131 \u00d6zelle\u015ftirme<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#SPA_Angular_AspNET_Core_Web_API_Keycloak_Browser_Flow_OTP_Dahil\" >SPA (Angular) + Asp.NET Core Web API + Keycloak Browser Flow (OTP Dahil)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-browser-flow-authentication-7\/#Browser_Flowda_En_Cok_Yapilan_Hatalar\" >Browser Flow&#8217;da En \u00c7ok Yap\u0131lan Hatalar<\/a><\/li><\/ul><\/nav><\/div>\n<br \/>\nBu i\u00e7eri\u011fimizde Asp.NET Core ile birlikte Keycloak&#8217;da <em>Browser Flow Authentication<\/em> konusunu hem teorik hem de pratik bir \u015fekilde netle\u015ftirebilece\u011fimiz bir incelemede bulunuyor olaca\u011f\u0131z.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Browser_Flow_Authentication_Nedir\"><\/span>Browser Flow Authentication Nedir?<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Browser Flow, Keycloak&#8217;un taray\u0131c\u0131 tabanl\u0131 (interactive) kimlik do\u011frulama senaryolar\u0131 i\u00e7in kulland\u0131\u011f\u0131 authentication flow t\u00fcr\u00fcd\u00fcr. Normalde bir web sitesine girildi\u011finde g\u00f6r\u00fclen login ekran\u0131, MFA ekran\u0131, hat\u0131rlatma cookie&#8217;si kontrol\u00fc vs. hepsi bu flow i\u00e7erisinde tan\u0131mlanmaktad\u0131r.<\/p>\n<p>Browser flow mant\u0131\u011f\u0131nda, uygulamalar kendi login ekranlar\u0131n\u0131 tasarlamamakta, oturum a\u00e7\u0131lmas\u0131 gerekti\u011fi taktirde uygulamalar kullan\u0131c\u0131lar\u0131 Keycloak&#8217;un login sayfas\u0131na y\u00f6nlendirerek gerekli oturum a\u00e7ma i\u015flemlerini orada sa\u011flamaktad\u0131r. B\u00f6ylece kullan\u0131c\u0131 \u015fifreleri, OTP de\u011ferleri vs. gibi kritik veriler client&#8217;lar taraf\u0131ndan eri\u015filemeyecek ve yaln\u0131zca Keycloak&#8217;un kendi ekran\u0131nda i\u015flenecektir. Bunlar\u0131n yan\u0131nda brute-force korumas\u0131 da sa\u011flanm\u0131\u015f olacakt\u0131r. B\u00f6ylece yap\u0131sal olarak merkezi bir do\u011frulama sistemi kurgulanm\u0131\u015f, g\u00fcvenlik a\u00e7\u0131s\u0131ndan da g\u00fc\u00e7lendirici hamleler sa\u011flanm\u0131\u015f olacakt\u0131r ve bir yandan da uygulamalardan da b\u00fcy\u00fck bir sorumluluk k\u00fclfeti kald\u0131r\u0131lm\u0131\u015f olacakt\u0131r.<\/p>\n<p>Ayr\u0131ca browser flow authentication sayesinde, <em>Tek Oturum A\u00e7ma<\/em> (veya <em>\u00c7oklu Oturum A\u00e7ma<\/em>) olarak bilinen <em><strong>Single Sign-On (SSO)<\/strong><\/em> do\u011frulama y\u00f6ntemi de otomatik sa\u011flanm\u0131\u015f olacakt\u0131r. Single Sign-On ile ayn\u0131 e-Devlet, Google yahut kurumsal ortamlarda oldu\u011fu gibi davran\u0131\u015f sergilenecek ve nas\u0131l ki bu ortamlarda oturum a\u00e7\u0131ld\u0131\u011f\u0131 taktirde, bunlarla ili\u015fkili (yani bunlarla merkezi kimlik kontrol\u00fc sa\u011flayan) di\u011fer sistemlere giri\u015f yap\u0131ld\u0131\u011f\u0131nda o oturum otomatik tan\u0131nacak ve do\u011frulanm\u0131\u015f olacakt\u0131r.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Single_Sign-On_SSO_nasil_calisir\"><\/span><em>Single Sign-On (SSO) nas\u0131l \u00e7al\u0131\u015f\u0131r?<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<ol style=\"font-size:14px;\">\n<li>Kullan\u0131c\u0131 ilk olarak herhangi bir X uygulamas\u0131na girer.<\/li>\n<li>Giri\u015f yapmak i\u00e7in butona t\u0131klar.<\/li>\n<li>X uygulamas\u0131, kullan\u0131c\u0131y\u0131 merkezi kimlik sa\u011flay\u0131c\u0131ya (Keycloak, e-Devlet, Google vs.) y\u00f6nlendirir.<\/li>\n<li>Kullan\u0131c\u0131 bu merkezi noktada \u015fifre, MFA vs. ile bir kez do\u011frulama ger\u00e7ekle\u015ftirir.<\/li>\n<li>Oturum ba\u015far\u0131l\u0131ysa bir session olu\u015fturulur ve taray\u0131c\u0131ya cookie\/token koyulur.<\/li>\n<li>Merkezi kimlik sa\u011flay\u0131c\u0131, X uygulamas\u0131na &#8220;kullan\u0131c\u0131 do\u011fruland\u0131&#8221; bilgisini, yani token&#8217;\u0131 verir.<\/li>\n<li>Kullan\u0131c\u0131 X uygulamas\u0131na y\u00f6nlendirilir.<\/li>\n<li>Sonra kullan\u0131c\u0131 Y uygulamas\u0131na girdi\u011finde bu uygulama merkezi kimlik sa\u011flay\u0131c\u0131s\u0131na gidecektir.<\/li>\n<li>Identity provider mevcut oturumu g\u00f6recektir.<\/li>\n<li>\u015eifre sormadan kullan\u0131c\u0131 do\u011frulanacak ve y uygulamas\u0131na da otomatik giri\u015f yap\u0131lm\u0131\u015f olacakt\u0131r.<\/li>\n<\/ol>\n<h5><span class=\"ez-toc-section\" id=\"SSOnun_avantajlari_ve_dezavantajlari_nelerdir\"><\/span><em>SSO&#8217;nun avantajlar\u0131 ve dezavantajlar\u0131 nelerdir?<\/em><span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Browser flow&#8217;un SSO davran\u0131\u015f\u0131 sayesinde birden fazla uygulama i\u00e7in kullan\u0131c\u0131 konforu olduk\u00e7a y\u00fckseltilmi\u015f olacakt\u0131r. <em>Neden mi?<\/em> \u00c7\u00fcnk\u00fc ne kadar uygulama o kadar \u015fifre y\u00f6netimi ve haf\u0131zas\u0131 gerektirecektir. Ki illaki bu \u015fifreler unutulacakt\u0131r&#8230; Ee bu da <em>\u015fifre yorgunlu\u011fu<\/em> anlam\u0131na gelen <u>password fatigue<\/u> durumuna sebebiyet verecektir <span style=\"font-size:14px;\">(Malumunuz \u00f6zellikle bankalar\u0131n sa\u00e7ma \u015fifre politikalar\u0131ndan dolay\u0131 ikrah etmi\u015f vaziyetteyiz)<\/span> Merkezi kimlik do\u011frulay\u0131c\u0131s\u0131ndan tek kullan\u0131c\u0131 ad\u0131 ve \u015fifre ile yap\u0131lan giri\u015flerin birden fazla uygulamay\u0131 kapsamas\u0131 olduk\u00e7a de\u011ferli bir konfor sa\u011flayacakt\u0131r. Ancak bu durumun getirisi oldu\u011fu kadar ciddi g\u00f6t\u00fcr\u00fcs\u00fc olabilecek bir riski de mevcuttur. O da; t\u00fcm sistemlere eri\u015fim ihtimalinin, o tek hesab\u0131n ele ge\u00e7irilmesine indirgenerek olas\u0131 riskin olduk\u00e7a artmas\u0131d\u0131r.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Browser_Flow_Ic_Yapisi\"><\/span>Browser Flow \u0130\u00e7 Yap\u0131s\u0131<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>\u015eimdi bizler i\u00e7in olduk\u00e7a \u00f6nemli olan browser flow i\u00e7 yap\u0131s\u0131n\u0131 de\u011ferlendirmeye ba\u015flayal\u0131m. Tabi bunu Keycloak inceleme serimizin 5. i\u00e7eri\u011fi olan <a href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-authentication-identity-identity-provider-ile-birlikte-authentication-flowlari-teorik-olarak-inceleyelim-5\/#Browser_Authentication_Flowu_Executionlarina_Bolelim\" target=\"_blank\">Keycloak\u2019da Authentication, Identity, Identity Provider \u0130le Birlikte Authentication Flow\u2019lar\u0131 Teorik Olarak \u0130nceleyelim<\/a> ba\u015fl\u0131kl\u0131 makalemizin <em>&#8220;Browser Authentication Flow&#8217;u Execution&#8217;lar\u0131na B\u00f6lelim&#8221;<\/em> ba\u015fl\u0131kl\u0131 b\u00f6l\u00fcm\u00fcnde <span style=\"font-size:14px;\">(ki linke t\u0131kland\u0131\u011f\u0131nda direkt ilgili ba\u015fl\u0131\u011fa gidecektir)<\/span> detayl\u0131ca teorik olarak inceledi\u011fimizi hat\u0131rlatmak isterim. Bundan kaynakl\u0131 ilgili ak\u0131\u015ftaki execution&#8217;lar\u0131 bir daha tek tek a\u00e7\u0131klama gere\u011fi g\u00f6rmemekteyim.<\/p>\n<p><em>Peki biz ne yapaca\u011f\u0131z?<\/em> diye sorarsan\u0131z, Keycloak&#8217;dan s\u00fcreci inceleyip bu ba\u015fl\u0131\u011f\u0131 biraz h\u0131zl\u0131 ge\u00e7ece\u011fiz. \u015eimdi bunun i\u00e7in;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"423\" height=\"416\" class=\"aligncenter size-full wp-image-28409\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7.png 423w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-300x295.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-80x80.png 80w\" sizes=\"auto, (max-width: 423px) 100vw, 423px\" \/><\/a>Keycloak \u00fczerinden Authentication sekmesine gelip, <code>browser<\/code> flow&#8217;a t\u0131klayal\u0131m ve ard\u0131ndan a\u00e7\u0131lan sayfada ak\u0131\u015fla ilgili t\u00fcm s\u00fcreci\/ad\u0131mlar\u0131 g\u00f6zlemleyelim.<div id=\"attachment_28410\" style=\"width: 1207px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-28410\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"1197\" height=\"871\" class=\"size-full wp-image-28410\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1.png 1197w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1-300x218.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1-1024x745.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-1-768x559.png 768w\" sizes=\"auto, (max-width: 1197px) 100vw, 1197px\" \/><\/a><p id=\"caption-attachment-28410\" class=\"wp-caption-text\">Keycloak&#8217;da Browser Flow Authentication ad\u0131mlar\u0131&#8230;<\/p><\/div><\/p>\n<h4><span class=\"ez-toc-section\" id=\"6_Kritik_Soru_6_Kritik_Cevap\"><\/span>6 Kritik Soru \/ 6 Kritik Cevap<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>\u015eimdi browser flow ile ilgili kritikleri soru cevap format\u0131nda ilerleyerek yapal\u0131m. B\u00f6ylece hem daha verimli bir yakla\u015f\u0131m sergilemi\u015f hem de ak\u0131llarda olabilecek sorular\u0131n cevaplar\u0131n\u0131 da pe\u015finen vermi\u015f olaca\u011f\u0131z&#8230;<\/p>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 1 | <span style=\"color:#877572;\">Browser flow ne zaman tetiklenir?<\/span><\/summary>\n<p>Taray\u0131c\u0131dan gelen, redirect tabanl\u0131 ve etkile\u015fim gerektiren OIDC isteklerinde.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 2 | <span style=\"color:#877572;\">Browser flow ba\u015far\u0131s\u0131z olursa ne olur?<\/span><\/summary>\n<p>Keycloak authorization code \u00fcretmez ve uygulamada da kullan\u0131c\u0131 authenticate edilemez!<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 3 | <span style=\"color:#877572;\">Browser flow token \u00fcretir mi?<\/span><\/summary>\n<p>Hay\u0131r. \u00c7\u00fcnk\u00fc, token \u00fcretimi flow&#8217;dan ayr\u0131 bir i\u015ftir! Flow, kimlik do\u011frulama s\u00fcrecidir ve bu s\u00fcre\u00e7 ba\u015far\u0131l\u0131ysa e\u011fer token \u00fcretilir. Yani browser flow&#8217;dan ba\u011f\u0131ms\u0131z olarak hangi ak\u0131\u015f olursa olsun dolayl\u0131 olarak evet, token \u00fcretimini flow tetikleyebilir.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 4 | <span style=\"color:#877572;\">Ayn\u0131 realm&#8217;de farkl\u0131 browser flow kullan\u0131labilir mi?<\/span><\/summary>\n<p>Client bazl\u0131 authentication flow override y\u00f6ntemi ile evet.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 5 | <span style=\"color:#877572;\">Cookie authenticator neden \u00f6nemlidir?<\/span><\/summary>\n<p>Her iste\u011fin login ekran\u0131na gitmemesi i\u00e7in Single Sign-On (SSO) sa\u011flar.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 6 | <span style=\"color:#877572;\">SPA&#8217;lar i\u00e7in browser flow tavsiye ediliyor mu?<\/span><\/summary>\n<p>Evet, hatta tek do\u011fru yol olarak.<br \/>\n<\/details>\n<h4><span class=\"ez-toc-section\" id=\"AspNET_Core_Keycloak_Browser_Flow_Ornek_Uygulama\"><\/span>Asp.NET Core | Keycloak | Browser Flow \u00d6rnek Uygulama<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>\u015eimdi Keycloak&#8217;daki browser flow&#8217;u Asp.NET Core MVC ile g\u00fczel bir \u015fekilde \u00f6rnek \u00fczerinden ele almaya ba\u015flayabiliriz. Bunun i\u00e7in bir Asp.NET Core MVC uygulamas\u0131 olu\u015ftural\u0131m ve i\u00e7erisine a\u015fa\u011f\u0131daki k\u00fct\u00fcphaneyi y\u00fckleyelim.<\/p>\n<div style=\"border:1px solid #e1e4e8;background:#f6f8fa;padding:16px;border-radius:8px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#24292e;word-break:break-all;\">\n  <strong style=\"display:block;margin-bottom:6px;color:#0969da;\">Gerekli K\u00fct\u00fcphaneler<\/strong><br \/>\n<a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.AspNetCore.Authentication.OpenIdConnect\" target=\"_blank\">Microsoft.AspNetCore.Authentication.OpenIdConnect<\/a>\n<\/div>\n<p>Bu paket, Asp.NET Core&#8217;un Keycloak <span style=\"font-size:14px;\">(yahut ba\u015fka bir Identity Provider)<\/span> ile <em>OpenID Connect (OIDC)<\/em> \u00fczerinden konu\u015fabilmesine yaramaktad\u0131r. Yani birazdan s\u00fcre\u00e7te g\u00f6rece\u011fimiz \u00fczere; taray\u0131c\u0131y\u0131 Keycloak&#8217;a y\u00f6nlendiren, <code>authorization code<\/code> edinen ve token endpoint&#8217;ine gidip token&#8217;\u0131 \u00e7eken esas\u0131nda bu k\u00fct\u00fcphanenin sa\u011flad\u0131\u011f\u0131 i\u015flevsellikler olacakt\u0131r.<\/p>\n<p><em style=\"font-size:15px;\">Hoca ekstradan paket kullanmadan i\u015f y\u00fcr\u00fctemez miyiz?<\/em><br \/>\nHay\u0131r, y\u00fcr\u00fctemezsiniz. Bu paket olmaks\u0131z\u0131n browser flow&#8217;u ba\u015flatamaz, authorization code&#8217;u alamaz, token endpoint&#8217;ten token edinemez ve external login yapamazs\u0131n\u0131z.<\/p>\n<p>\u015eimdi i\u015fin mant\u0131\u011f\u0131n\u0131 kavrayak ilerleyelim ve bu \u00e7er\u00e7evede yap\u0131land\u0131rmalar\u0131 ad\u0131m ad\u0131m ger\u00e7ekle\u015ftirelim.<\/p>\n<p>Tabi ilk olarak olu\u015fturdu\u011fumuz uygulamay\u0131 Keycloak&#8217;ta temsil edecek olan client&#8217;\u0131 tasarlayal\u0131m&#8230;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-2.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"499\" height=\"827\" class=\"aligncenter size-full wp-image-28417\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-2.png 499w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-2-181x300.png 181w\" sizes=\"auto, (max-width: 499px) 100vw, 499px\" \/><\/a>Dikkat ederseniz, <em>application-client<\/em> ad\u0131n\u0131 vermi\u015f oldu\u011fumuz bir confidential client olu\u015fturmu\u015f bulunuyoruz. Bu client&#8217;\u0131n browser flow&#8217;u destekleyebilmesi i\u00e7in \u00f6zellikle <em>Standard flow<\/em>&#8216;un i\u015faretlenmesi ve ekran al\u0131nt\u0131s\u0131nda vurgulanm\u0131\u015f olan url&#8217;lerin do\u011fru bir \u015fekilde girilmesi gerekmektedir.<\/p>\n<p>Ard\u0131ndan uygulaman\u0131n <em>Program.cs<\/em> dosyas\u0131nda a\u015fa\u011f\u0131daki yap\u0131land\u0131rmay\u0131 sa\u011flayal\u0131m:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddAuthentication(options =&gt;\r\n    {\r\n        \/\/Varsay\u0131lan kimlik do\u011frulama \u015femas\u0131 olarak Cookie tabanl\u0131 kimlik do\u011frulama kullan\u0131lmaktad\u0131r.\r\n        \/\/Yani kullan\u0131c\u0131 oturum bilgileri cookie'de saklan\u0131r.\r\n        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\r\n        \/\/Kullan\u0131c\u0131, yetkisiz olarak kimlik do\u011frulama gerektiren bir sayfaya eri\u015fmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda\r\n        \/\/OpenID Connect protokol\u00fc kullan\u0131larak kimlik do\u011frulama i\u015flemi ba\u015flat\u0131l\u0131r ve Keycloak'a y\u00f6nlendirme sa\u011flan\u0131r.\r\n        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;\r\n    })\r\n    .AddCookie(options =&gt;\r\n    {\r\n        \/\/Kullan\u0131c\u0131 giri\u015f yapmad\u0131\u011f\u0131nda y\u00f6nlendirilece\u011fi sayfa.\r\n        options.LoginPath = &quot;\/login&quot;;\r\n        \/\/Kullan\u0131c\u0131 \u00e7\u0131k\u0131\u015f yapt\u0131\u011f\u0131nda y\u00f6nlendirilece\u011fi sayfa.\r\n        options.LogoutPath = &quot;\/logout&quot;;\r\n    })\r\n    \/\/OpenID Connect protokol\u00fc kullan\u0131larak Keycloak ile entegrasyon sa\u011flan\u0131lmaktad\u0131r.\r\n    .AddOpenIdConnect(options =&gt;\r\n    {\r\n        options.Authority = &quot;http:\/\/127.0.0.1:8080\/realms\/master&quot;;\r\n        options.ClientId = &quot;application-client&quot;;\r\n        options.ClientSecret = &quot;xgVgEbqi5jxpZ0QvQDSVQMIlmsw2gbZv&quot;;\r\n        options.ResponseType = &quot;code&quot;;\r\n\r\n        options.SaveTokens = true;\r\n        options.GetClaimsFromUserInfoEndpoint = true;\r\n        options.RequireHttpsMetadata = false;\r\n\r\n        options.Scope.Clear();\r\n        options.Scope.Add(&quot;openid&quot;);\r\n        options.Scope.Add(&quot;profile&quot;);\r\n        options.Scope.Add(&quot;email&quot;);\r\n\r\n        options.CallbackPath = &quot;\/signin-oidc&quot;;\r\n\r\n        options.TokenValidationParameters = new()\r\n        {\r\n            NameClaimType = &quot;preferred_username&quot;,\r\n            RoleClaimType = &quot;roles&quot;\r\n        };\r\n    });\r\n<\/pre>\n<\/div>\n<p>Burada yap\u0131lan \u00e7al\u0131\u015fmay\u0131 izah etmemiz gerekirse e\u011fer;<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong>5 &#8211; 8. sat\u0131r aral\u0131\u011f\u0131;<\/strong> Burada Asp.NET Core&#8217;un bu request s\u00fcrecinde hangi authentication mekanizmas\u0131n\u0131 kullanaca\u011f\u0131n\u0131 ifade ediyoruz. Dikkat ederseniz, iki yap\u0131land\u0131rma da farkl\u0131 zamanlarda, farkl\u0131 ama\u00e7larla kullan\u0131lmaktad\u0131rlar.<br \/>\n1\ufe0f\u20e3<code style=\"color:green;\">DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme<\/code><br \/>\nBu \u015fema yap\u0131land\u0131rmas\u0131, gelen request&#8217;te kullan\u0131c\u0131 authenticate mi diye kontrol edilecekse nereden edilece\u011fini belirtmektedir. Cookie&#8217;den \ud83d\ude42<\/p>\n<div style=\"background-color: #f4f4f4; padding: 15px; border-left: 5px solid #3498db; margin: 20px 0; font-style: italic; color: #333; font-size: 14px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); border-radius: 8px; width: 40%; float: right; box-sizing: border-box;\">\n  <strong><em>Challenge nedir?<\/em><\/strong> Challenge, kimlik do\u011frulama s\u00fcrecinde <em>-kullan\u0131c\u0131 do\u011frulanmam\u0131\u015f, \u015fimdi onu login olmaya y\u00f6nlendiriyorum-<\/em> anlam\u0131na gelen bir mekanizmad\u0131r. Asp.NET Core mimarisi, bir kullan\u0131c\u0131 herhangi bir korumal\u0131 kayna\u011fa sistemde onun kimli\u011fini do\u011frulayacak ge\u00e7erli bir bilgi (cookie veya token) olmadan eri\u015fmeye \u00e7al\u0131\u015f\u0131rsa, bu iste\u011fi reddetmek yerine Challenge&#8217;\u0131 tetikler ve \u00f6nceden tan\u0131mlanm\u0131\u015f <em>Challenge Scheme<\/em> \u00fczerinden login s\u00fcrecini ba\u015flat\u0131r. SPA&#8217;larda da Challenge mant\u0131\u011f\u0131 mevcuttur.\n<\/div>\n<p><em>Ne zaman devreye girer?<\/em><br \/>\n<code>[Authorize]<\/code> attribute&#8217;u \u00e7al\u0131\u015ft\u0131\u011f\u0131nda ve <code>HttpContext.User<\/code> doldurulurken&#8230;<\/p>\n<p>2\ufe0f\u20e3<code style=\"color:green;\">DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme<\/code><\/p>\n<p>Bu \u015fema yap\u0131land\u0131rmas\u0131 ise kullan\u0131c\u0131n\u0131n authenticate olmad\u0131\u011f\u0131 durumda, onu nas\u0131l login&#8217;e y\u00f6nlendirece\u011finin cevab\u0131n\u0131 verir. Burada verilen cevap &#8216;<em>OpenIdConnect<\/em>&#8216; \u015feklindedir.<\/p>\n<p><em>Ne zaman devreye girer?<\/em><br \/>\n<code>[Authorize]<\/code> attribute&#8217;u \u00e7al\u0131\u015ft\u0131\u011f\u0131nda ve kullan\u0131c\u0131n\u0131n authenticated olmad\u0131\u011f\u0131 anla\u015f\u0131l\u0131nca.<\/p>\n<p>Bu yap\u0131land\u0131rma sayesinde Asp.NET Core kullan\u0131c\u0131y\u0131 Keycloak login&#8217;e y\u00f6nlendirecektir. Bu faaliyete <strong><em>Challenge<\/em><\/strong> denmektedir!<br \/>&nbsp;<br \/>&nbsp;<\/p>\n<div style=\"background-color: #f4f4f4; padding: 15px; border-left: 5px solid #3498db; margin: 20px 0; font-style: italic; color: #333; font-size: 14px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); border-radius: 8px; width: 40%; float: right; box-sizing: border-box;\">\n  <strong><em>Authorization Code nedir?<\/em><\/strong> Authorization Code, -kullan\u0131c\u0131n\u0131n ba\u015far\u0131yla kimli\u011fi do\u011fruland\u0131- bilgisini temsil eden k\u0131sa \u00f6m\u00fcrl\u00fc, tek kullan\u0131ml\u0131, ge\u00e7ici bir koddur.<\/p>\n<p>Bizler; kullan\u0131c\u0131 yetkisini ifade eden ger\u00e7ek token&#8217;\u0131 taray\u0131c\u0131ya vermek veya url&#8217;de ta\u015f\u0131mak istemedi\u011fimiz i\u00e7in token yerine de\u011fersiz ve bir anlam\u0131 olmayan Authorization Code&#8217;u kullan\u0131yoruz. Bundan kaynakl\u0131 Authorization Code;<br \/>\n<span style=\"color:#CC877A;\">\u2192Token de\u011fildir!<br \/>\n\u2192Yetki vermemektedir!<br \/>\n\u2192API \u00e7a\u011fr\u0131s\u0131nda kullan\u0131lmamaktad\u0131r!<\/span><br \/>\nYaln\u0131zca token almak i\u00e7in kullan\u0131lan \u00f6zel bir koddur. Bu kod ile uygulama, arka planda Keycloak&#8217;dan ger\u00e7ek token&#8217;\u0131 elde edebilmektedir.\n<\/div>\n<blockquote><p><em>Challenge, Asp.NET Core&#8217;un \u015funu demesidir; \u015fimdi bu kullan\u0131c\u0131y\u0131 do\u011frulanabilece\u011fi bir yere y\u00f6nlendiriyorum&#8230;<\/em><\/p><\/blockquote>\n<\/li>\n<li><strong>23. sat\u0131r;<\/strong> <code>options.ResponseType = \"code\"<\/code> Bu yap\u0131land\u0131rmayla login&#8217;in ba\u015far\u0131l\u0131 olmas\u0131 durumunda Keycloak&#8217;un bize ne d\u00f6nd\u00fcrece\u011fini yap\u0131land\u0131rm\u0131\u015f oluyoruz.\n<p><code>code<\/code> diyerek <em>Authorization Code Flow<\/em>&#8216;u ifade etmi\u015f oluyoruz.<\/p>\n<blockquote><p><em>code, bir token talebi de\u011fil, token&#8217;a giden g\u00fcvenli biletin(authorization code) ta kendisidir!<\/em><\/p><\/blockquote>\n<\/li>\n<li><strong>25. sat\u0131r;<\/strong><code>options.SaveTokens = true<\/code> OIDC ile al\u0131nan token&#8217;lar\u0131n (access, id, refresh) Asp.NET Core authentication ticket&#8217;\u0131na kaydedilmesini sa\u011flar. Yani, normal \u015fartlarda token al\u0131nd\u0131\u011f\u0131 taktirde herhangi bir yerde saklanmamaktad\u0131r. Ancak <code>SaveTokens = true<\/code> dendi\u011finde token&#8217;lar, o anki login i\u015flemiyle ilgili ek bilgileri bar\u0131nd\u0131ran <code>AuthenticationProperties<\/code> i\u00e7erisine eklenecektir ve Cookie&#8217;ye \u015fifreli \u015fekilde g\u00f6m\u00fclecektir. B\u00f6ylece bizler request s\u00fcrecinde istedi\u011fimiz noktada <code>HttpContext.GetTokenAsync(\"access_token\")<\/code> \u015feklinde token&#8217;a eri\u015fim g\u00f6sterebiliyor olaca\u011f\u0131z.<br \/>\n<blockquote><p><em><code>SaveTokens = true<\/code>, -ald\u0131\u011f\u0131m token&#8217;lar\u0131 sakla ki sonra kullanabileyim- demektir.<\/em><\/p><\/blockquote>\n<p>Burada <code>AuthenticationProperties<\/code>&#8216;i claim&#8217;ler yahut <code>User.Identity<\/code> ile kar\u0131\u015ft\u0131rmamak laz\u0131md\u0131r. Bu, sadece authentication ticket&#8217;\u0131n bir par\u00e7as\u0131d\u0131r&#8230;\n<\/li>\n<li><strong>26. sat\u0131r;<\/strong><code>options.GetClaimsFromUserInfoEndpoint = true<\/code> Bu, kullan\u0131c\u0131 oturumu ba\u015far\u0131yla a\u00e7t\u0131ktan yani do\u011fruland\u0131ktan sonra Asp.NET Core uygulamas\u0131na Keycloak&#8217;un \/userinfo endpoint&#8217;ine ekstra bir \u00e7a\u011fr\u0131 yapmas\u0131n\u0131 ve kullan\u0131c\u0131 bilgilerini oradan almas\u0131n\u0131 s\u00f6yleyen bir yap\u0131land\u0131rmad\u0131r.<\/li>\n<li><strong>29 &#8211; 32. sat\u0131r aral\u0131\u011f\u0131;<\/strong> Login olurken belirtilen kapsamlar (scopes) dahilinde bilgi istendi\u011fi ifade edilmektedir. Normalde, varsay\u0131lan olarak <code>AddOpenIdConnect<\/code> yap\u0131land\u0131rmas\u0131nda <code>openid<\/code> ve <code>profile<\/code> scope&#8217;lar\u0131 otomatik eklenmektedir.<\/li>\n<li><strong>34. sat\u0131r;<\/strong><code>options.CallbackPath = \"\/signin-oidc\"<\/code> Keycloak&#8217;un login bitti\u011fi taktirde taray\u0131c\u0131y\u0131 geri d\u00f6nd\u00fcrece\u011fi callback adresini ifade etmektedir. Bu adres \u00fczerinden \u00fcretilen token e\u015fli\u011finde kullan\u0131c\u0131 uygulamaya geri d\u00f6nd\u00fcr\u00fclm\u00fc\u015f olur.<\/li>\n<\/ul>\n<p>Evet, olmas\u0131 gereken altyap\u0131y\u0131 art\u0131k yap\u0131land\u0131rd\u0131\u011f\u0131m\u0131z\u0131 s\u00f6yleyebilirim. Bundan sonras\u0131 hafif ince i\u015f\u00e7ilik. Haliyle gelin \u015fimdi login ve logout action&#8217;lar\u0131n\u0131 halledelim:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class AccountController : Controller\r\n    {\r\n        &#x5B;HttpGet(&quot;\/login&quot;)]\r\n        public IActionResult Login(string returnUrl = &quot;\/&quot;)\r\n            =&gt; Challenge(new AuthenticationProperties { RedirectUri = returnUrl }, OpenIdConnectDefaults.AuthenticationScheme);\r\n\r\n        &#x5B;Authorize]\r\n        &#x5B;HttpGet(&quot;\/logout&quot;)]\r\n        public IActionResult Logout()\r\n        {\r\n            return SignOut(new AuthenticationProperties { RedirectUri = &quot;\/&quot; }, CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Uygulamada login ve logout talepleri oldu\u011fu taktirde bu action&#8217;lar tetiklenecektir. Burada dikkat ederseniz <code>AuthenticationProperties<\/code> yap\u0131land\u0131rmas\u0131 e\u015fli\u011finde <code>Challenge<\/code> ve <code>SignOut<\/code> metotlar\u0131ndan istifade edilmektedir.<\/p>\n<p><code>Challenge<\/code> metodu, <code>[Authorize]<\/code> olan bir endpoint&#8217;e login olmam\u0131\u015f kullan\u0131c\u0131dan gelen request neticesinde otomatik tetiklenece\u011fi gibi, buradaki \u00f6rnekte oldu\u011fu gibi manuel de tetiklenebilmektedir. Bu tetikleme ger\u00e7ekle\u015fti\u011fi taktirde <code>OpenIdConnect<\/code> \u015femas\u0131ndaki yap\u0131land\u0131rmalar devreye girecek ve kullan\u0131c\u0131 Keycloak&#8217;a login s\u00fcrecinin ba\u015flamas\u0131 i\u00e7in y\u00f6nlendirilecektir.<\/p>\n<p><code>SignOut<\/code> metodu ise <em>-mevcut kimli\u011fi art\u0131k ge\u00e7ersiz say-<\/em> demektir. Yani bu metot ile Asp.NET Core cookie&#8217;si silinecek ve kullan\u0131c\u0131 uygulamadan \u00e7\u0131kar\u0131lacakt\u0131r. <u>Ama unutulmamal\u0131d\u0131r ki, SSO a\u00e7\u0131k kalacakt\u0131r!<\/u> Burada, <em>Program.cs<\/em>&#8216;de yap\u0131land\u0131r\u0131lm\u0131\u015f her iki \u015feman\u0131n \u00f6zellikle belirtildi\u011fini g\u00f6r\u00fcyoruz. Bunun nedeni, hem Asp.NET Core&#8217;da sadece uygulamay\u0131 ilgilendirecek \u015fekilde i\u00e7 logout&#8217;u ger\u00e7ekle\u015ftirmek hem de Keycloak&#8217;a kullan\u0131c\u0131yla ilgili logout olundu\u011funun bilgisini vermektir. <code>OpenIdConnectDefaults.AuthenticationScheme<\/code>, bu ikinci eylemi ger\u00e7ekle\u015ftirecektir ve Keycloak&#8217;\u0131n <code>\/protocol\/openid-connect\/logout<\/code> endpoint&#8217;ine giderek, ilgili kullan\u0131c\u0131n\u0131n session&#8217;\u0131n\u0131 d\u00fc\u015f\u00fcrecektir. Evet, bu eylem sonunda kullan\u0131c\u0131n\u0131n aktif session&#8217;lar\u0131 listesinin g\u00fcncellendi\u011fi g\u00f6zlemlenebilecektir. Haliyle burada her iki \u015feman\u0131n da verilmesine kesinlikle \u00f6zen g\u00f6sterilmelidir.<\/p>\n<div style=\"display: flex; justify-content: space-between; gap: 20px; margin: 20px; padding: 20px; background-color: #f9f9f9; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\">\n<div style=\"flex: 1; padding: 20px; background-color: #ffffff; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); text-align: center;\">\n    <span style=\"color: #333; font-size: 24px; margin-bottom: 10px;\">Sadece Cookie verirsen<\/span><\/p>\n<p style=\"color: #777; font-size: 16px;\">Uygulamadan \u00e7\u0131k\u0131l\u0131r, Keycloak hala login kal\u0131r. Kullan\u0131c\u0131 uygulamaya geldi\u011fi an \u015fifresiz otomatik giri\u015f sa\u011flan\u0131r.<\/p>\n<\/p><\/div>\n<div style=\"flex: 1; padding: 20px; background-color: #ffffff; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); text-align: center;\">\n    <span style=\"color: #333; font-size: 24px; margin-bottom: 10px;\">Sadece OIDC verirsen<\/span><\/p>\n<p style=\"color: #777; font-size: 16px;\">Keycloak logout olur ama uygulama cookie&#8217;si tutulur. Haliyle uygulama hala login olarak yoluna devam eder.<\/p>\n<\/p><\/div>\n<\/div>\n<p>Evet, art\u0131k uygulamay\u0131 test edebiliriz. Tabi bunun i\u00e7in a\u015fa\u011f\u0131daki gibi iki adet action tasarlamam\u0131z yeterli olacakt\u0131r:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class HomeController : Controller\r\n    {\r\n        public IActionResult Index()\r\n        {\r\n            ViewBag.Title = &quot;Index&quot;;\r\n            return View();\r\n        }\r\n\r\n        &#x5B;Authorize]\r\n        public IActionResult Detail()\r\n        {\r\n            ViewBag.Title = &quot;Detail&quot;;\r\n            return View();\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bu action&#8217;lardan birine direkt eri\u015fim sa\u011flanabilirken bir di\u011feri ise yetkilendirme beklemektedir.<\/p>\n<p>Son olarak <em>Program.cs<\/em> dosyas\u0131na a\u015fa\u011f\u0131daki middleware&#8217;lerini ekleyelim ve uygulamay\u0131 derleyip, aya\u011fa kald\u0131ral\u0131m&#8230;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.UseAuthentication();\r\napp.UseAuthorization();\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7.gif\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"1280\" height=\"725\" class=\"aligncenter size-full wp-image-28419\" \/><\/a><\/p>\n<h4><span class=\"ez-toc-section\" id=\"Login_Ekranini_Ozellestirme\"><\/span>Login Ekran\u0131n\u0131 \u00d6zelle\u015ftirme<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Keycloak&#8217;ta \u00f6nceden tasarlanm\u0131\u015f haz\u0131r temalar mevcuttur. Bunlar;<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:16px;white-space:pre;line-height:0.8;padding:12px;width:300px;\">\nkeycloak\/<br \/>\n \u2514\u2500\u2500 themes\/<br \/>\n     \u2514\u2500\u2500 base\/<br \/>\n     \u2514\u2500\u2500 keycloak\/<br \/>\n     \u2514\u2500\u2500 keycloak.v2\/\n<\/div>\n<p>temalar\u0131d\u0131r. Her \u015feyden \u00f6nce \u00f6zelle\u015ftirme niyetiyle <em>base<\/em> ve <em>keycloak<\/em> temalar\u0131n\u0131n asla de\u011fi\u015ftirilmemesini \u00f6nermekteyim. E\u011fer varsa yeni bir tasar\u0131ma ihtiya\u00e7, bunun s\u0131f\u0131rdan bir tema tasarlayarak giderilmesi en do\u011frusu olacakt\u0131r.<\/p>\n<p><em>Nas\u0131l m\u0131?<\/em><br \/>\nKeycloak&#8217;da login ekranlar\u0131 FreeMarker (.ftl) template&#8217;leri ile \u00fcretilmektedir. Haliyle bu davran\u0131\u015fta bir tema olu\u015fturulmas\u0131 yeterli olacakt\u0131r. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi bir klas\u00f6r dizinine ve dosya yap\u0131lanmas\u0131na ihtiya\u00e7 vard\u0131r;<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:16px;white-space:pre;line-height:0.8;padding:12px;width:320px;\">\nthemes\/<br \/>\n \u2514\u2500\u2500 my-login-theme\/<br \/>\n     \u2514\u2500\u2500 login\/<br \/>\n         \u251c\u2500\u2500 login.ftl<br \/>\n         \u251c\u2500\u2500 login-reset-password.ftl<br \/>\n         \u251c\u2500\u2500 login-otp.ftl<br \/>\n         \u251c\u2500\u2500 theme.properties<br \/>\n         \u2514\u2500\u2500 resources\/<br \/>\n             \u251c\u2500\u2500 css\/<br \/>\n             \u2502   \u2514\u2500\u2500 style.css<br \/>\n             \u2514\u2500\u2500 img\/\n<\/div>\n<p>Burada ben sizler i\u00e7in g\u00fczel bir template tasarlam\u0131\u015f bulunuyorum.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-4.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"1010\" height=\"692\" class=\"aligncenter size-full wp-image-28423\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-4.png 1010w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-4-300x206.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-4-768x526.png 768w\" sizes=\"auto, (max-width: 1010px) 100vw, 1010px\" \/><\/a>Evet&#8230; G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere egzotik havas\u0131yla, kayan y\u0131ld\u0131zlar e\u015fli\u011finde gayet ferah ve estetik bir tasar\u0131m ortaya koymu\u015f bulunuyorum <span style=\"font-size:12px;\">(tasar\u0131m hafif bi i*nems* olmad\u0131 de\u011fil de neyse)<\/span> Bu template&#8217;i indirebilmek i\u00e7in i\u00e7eri\u011fimizin sonundaki GitHub reposuna gitmeniz yeterli olacakt\u0131r. Ha yaz\u0131y\u0131 b\u00f6lmeden direkt indirmek istiyorsan\u0131z <a href=\"https:\/\/github.com\/gncyyldz\/Keycloak.Examples\/tree\/Keycloak4.AspNetCore-%C4%B0le-Browser-Flow-Authentication\/Custom%20Theme\/keycloak-login-theme\/login\" target=\"_blank\">buradaki<\/a> linkten eri\u015febilirsiniz.<\/p>\n<p><strong><em>Peki bu template&#8217;i Keycloak&#8217;a nas\u0131l y\u00fckleyece\u011fiz?<\/em><\/strong><br \/>\nKeycloak&#8217;da template&#8217;ler <code>\/opt\/keycloak\/themes\/<\/code> dizininde tutulmaktad\u0131rlar. Dolay\u0131s\u0131yla ana klas\u00f6r\u00fc bu dizine at\u0131p, Keycloak Admin Dashboard&#8217;undan da<br \/>\n<span style=\"font-size:14px;\"><code>Realm settings<\/code> \u2192 <code>Themes<\/code> \u2192 <code>Login theme<\/code><\/span> kombinasyonunu takip ederek ilgili temay\u0131 se\u00e7erseniz hem y\u00fcklemi\u015f hem de flow s\u00fcrecinde tasar\u0131m\u0131 aktifle\u015ftirmi\u015f olacaks\u0131n\u0131z.<\/p>\n<div style=\"background:#0f172a;color:#e5e7eb;padding:20px;border-radius:12px;box-shadow:0 10px 25px rgba(0,0,0,0.35);font-family:Menlo,Monaco,Consolas,monospace;position:relative;overflow:hidden;\">\n<div style=\"position:absolute;top:0;left:0;width:100%;height:4px;background:linear-gradient(90deg,#22d3ee,#38bdf8,#6366f1);\"><\/div>\n<div style=\"font-size:13px;color:#94a3b8;margin-bottom:10px;letter-spacing:0.5px;\">Docker container&#8217;da aya\u011fa kald\u0131r\u0131lan Keycloak&#8217;a custom template&#8217;i y\u00fckleyebilmek i\u00e7in a\u015fa\u011f\u0131daki talimat\u0131 kullanabilirsiniz.<\/div>\n<p>  <span style=\"margin:0;font-size:15px;line-height:1.6;color:#e5e7eb;white-space:pre-wrap;\">docker cp <span style=\"color:orange;\">{keycloak_custom_template_path}<\/span> <span style=\"color:orange;\">{keycloak_container_name}<\/span>:\/opt\/keycloak\/themes\/keycloak-custom-login-theme<\/span>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-5.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"692\" height=\"417\" class=\"aligncenter size-full wp-image-28424\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-5.png 692w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-5-300x181.png 300w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/a><\/p>\n<h4><span class=\"ez-toc-section\" id=\"SPA_Angular_AspNET_Core_Web_API_Keycloak_Browser_Flow_OTP_Dahil\"><\/span>SPA (Angular) + Asp.NET Core Web API + Keycloak Browser Flow (OTP Dahil)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Evet, art\u0131k i\u00e7eri\u011fimizde pratiksel olarak son dokunu\u015fu en \u00e7ok merak edilen ve kritik olan bir noktaya temas ederek ger\u00e7ekle\u015ftirelim istiyorum. <em>SPA (Single Page Application) kullanan projelerde browser flow tam olarak nas\u0131l ger\u00e7ekle\u015ftiriliyor?<\/em> Bu ba\u015fl\u0131k alt\u0131nda bu soruya net bir cevap vermeye ve hatta basit ama a\u00e7\u0131klay\u0131c\u0131 bir \u00f6rnek \u00e7al\u0131\u015fmayla konuyu peki\u015ftirerek cevab\u0131 ta\u00e7land\u0131rmaya \u00e7al\u0131\u015faca\u011f\u0131z.<\/p>\n<p><em><strong>Cookie mi, JWT mi?<\/strong><\/em><br \/>\n\u00d6ncelikle \u015funu bilmekte fayda vard\u0131r ki; SPA, yap\u0131s\u0131 gere\u011fi cookie&#8217;ye pek de uygun de\u011fildir. <em>Neden mi?<\/em> \u00c7\u00fcnk\u00fc; HttpOnly cookie, JavaScript ile okunamamaktad\u0131r. <em>Ee bu g\u00fcvenli bir durum de\u011fil mi?<\/em> diye sorarsan\u0131z, evet, belki g\u00fcvenlidir ancak SPA tamamen JavaScript temelli oldu\u011fu i\u00e7in bu durumda token&#8217;\u0131 cookie&#8217;den okuyup kullanamayacakt\u0131r.<\/p>\n<p>Ayr\u0131ca SPA yap\u0131sal olarak ayn\u0131 backend&#8217;i mobil gibi, masa\u00fcst\u00fc ya da IoT gibi farkl\u0131 uygulamalarla payla\u015ft\u0131\u011f\u0131ndan dolay\u0131, haliyle cookie, sadece browser&#8217;a \u00f6zg\u00fc bir yap\u0131ya sahiptir. Oysaki JWT her yerde kullan\u0131labilmektedir.<\/p>\n<p>Bundan kaynakl\u0131 bizler SPA ile \u00e7al\u0131\u015f\u0131rken genellikle JWT&#8217;yi tercih etmekte ve ona g\u00f6re davran\u0131\u015f\u0131m\u0131z\u0131 \u015fekillendirmekteyiz. Haliyle buradaki \u00e7al\u0131\u015fmada da JWT ile browser flow&#8217;a e\u015flik edece\u011fiz. <\/p>\n<p>\u015eimdi bir Angular projesi e\u015fli\u011finde, Asp.NET Core Web API projesi olu\u015ftural\u0131m ve yapaca\u011f\u0131m\u0131z \u00e7al\u0131\u015fmalar\u0131 a\u015fa\u011f\u0131da gibi ad\u0131m ad\u0131m ger\u00e7ekle\u015ftirelim.<\/p>\n<ul style=\"font-size:14px;\">\n<li><em><strong>Ad\u0131m 1<\/strong> <span style=\"color:green;font-size:13px;\">(Keycloak&#8217;da SPA Client&#8217;\u0131 Olu\u015fturma)<\/span><\/em><br \/>\nHer \u015feyden \u00f6nce SPA uygulamas\u0131n\u0131 Keycloak&#8217;da temsil edecek bir client olu\u015fturarak i\u015fe ba\u015flamam\u0131z gerekmektedir. Bunun i\u00e7in <code>angular-client<\/code> ad\u0131nda ve a\u015fa\u011f\u0131daki \u00f6zelliklerde bir client olu\u015ftural\u0131m.<\/p>\n<div style=\"color:#df3079\">\nStandard Flow Enabled: \u2705<br \/>\nImplicit Flow: \u274c<br \/>\nDirect Access Grants: \u274c<br \/>\nClient Authentication: \u274c (KAPALI) &#8211; <span style=\"color:gray;font-size:12px;\">(Client authentication, client secret de\u011ferini gerektirece\u011fi ve SPA&#8217;da da bu de\u011fer g\u00fcvenli bir \u015fekilde tutulamayaca\u011f\u0131 (tutulsa da gizlenemeyece\u011fi) i\u00e7in SPA&#8217;da kullan\u0131lmamaktad\u0131r.)<\/span>\n<\/div>\n<div style=\"color:#e9950c\">\nRedirect URI: http:\/\/localhost:4200\/*<br \/>\nWeb Origins: http:\/\/localhost:4200\n<\/div>\n<p><strong><em style=\"color:gray;\">Ee hoca, signin-oidc&#8217;yi tan\u0131mlamayacak m\u0131y\u0131z?<\/em><\/strong><br \/>\n<code>signin-oidc<\/code>, Asp.NET Core OpenIdConnect middleware&#8217;i taraf\u0131ndan otomatik olu\u015fturulmaktad\u0131r ve server-side web app, cookie authentication ve AddOpenIdConnect senaryolar\u0131nda kullan\u0131lmaktad\u0131r. SPA&#8217;da ise <code>signin-oidc<\/code> diye bir endpoint mevcut olmayaca\u011f\u0131 i\u00e7in callback, root route&#8217;a ya da herhangi bir client-side route&#8217;a y\u00f6nlendirilebilir.\n<\/li>\n<li><em><strong>Ad\u0131m 2<\/strong> <span style=\"color:green;font-size:13px;\">(Keycloak&#8217;da Backend Client&#8217;\u0131 Olu\u015fturma)<\/span><\/em><br \/>\n\u015eimdi de Asp.NET Core Web API uygulamas\u0131 i\u00e7in <code>angular-api-client<\/code> ad\u0131nda Keycloak&#8217;da bir client olu\u015ftural\u0131m. Bu client, SPA&#8217;dan gelen token&#8217;\u0131 do\u011frulay\u0131p onu besleyen backend g\u00f6revi g\u00f6rece\u011finden t\u00fcm flow&#8217;lar\u0131 kapal\u0131 olacakt\u0131r ve root url&#8217;i felan da olmayacakt\u0131r.\n<\/li>\n<li><em><strong>Ad\u0131m 3<\/strong> <span style=\"color:green;font-size:13px;\">(Browser Flow&#8217;u Kopyalama ve SPA&#8217;da Uygun Hale Getirme)<\/span><\/em><br \/>\nSPA ile Asp.NET Core senaryosu i\u00e7in mevcut browser flow&#8217;u <code>spa_browser<\/code> ad\u0131nda kopyalay\u0131p i\u00e7eri\u011fini a\u015fa\u011f\u0131daki gibi \u00f6zelle\u015ftirelim.<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:430px;\">\nBrowser<br \/>\n \u251c\u2500\u2500 Cookie (ALTERNATIVE)<br \/>\n \u251c\u2500\u2500 Identity Provider Redirector (ALTERNATIVE)<br \/>\n \u251c\u2500\u2500 Username Password Form (REQUIRED)<br \/>\n \u2514\u2500\u2500 Conditional OTP (REQUIRED)<br \/>\n      \u251c\u2500\u2500 Condition &#8211; User Configured (REQUIRED)<br \/>\n      \u2514\u2500\u2500 OTP Form (REQUIRED)\n<\/div>\n<p>Evet, b\u00f6ylece bir SPA i\u00e7in olduk\u00e7a ideal flow tasarlam\u0131\u015f bulunuyoruz. Ard\u0131ndan bu flow&#8217;u bind ederek, Keycloak&#8217;da aktifle\u015ftirelim.\n<\/li>\n<li><em><strong>Ad\u0131m 4<\/strong> <span style=\"color:green;font-size:13px;\">(Angular&#8217;da Keycloak JS Adapter&#8217;\u0131 Y\u00fckleme ve Temel Servisi \u0130n\u015fa Etme)<\/span><\/em><br \/>\nKeycloak\u2019un SPA\u2019ler i\u00e7in resmi olarak sundu\u011fu <a href=\"https:\/\/www.npmjs.com\/package\/keycloak-js\" target=\"_blank\" class=\"broken_link\">keycloak-js<\/a> JavaScript client k\u00fct\u00fcphanesini kullanarak login, logout, token alma ve token yenileme i\u015flemlerini Keycloak\u2019a devredece\u011fiz. Haliyle \u00f6ncelikle bu paketi uygulamaya y\u00fckleyelim;<\/p>\n<div style=\"background:#0f172a;color:#e5e7eb;padding:20px;border-radius:12px;box-shadow:0 10px 25px rgba(0,0,0,0.35);font-family:Menlo,Monaco,Consolas,monospace;position:relative;overflow:hidden;\">\n<div style=\"position:absolute;top:0;left:0;width:100%;height:4px;background:linear-gradient(90deg,#22d3ee,#38bdf8,#6366f1);\"><\/div>\n<div style=\"font-size:13px;color:#94a3b8;margin-bottom:10px;letter-spacing:0.5px;\">keycloak-js<\/div>\n<p>  <span style=\"margin:0;line-height:1.6;color:#e5e7eb;white-space:pre-wrap;\">npm install keycloak-js<\/span>\n<\/div>\n<p>Ard\u0131ndan a\u015fa\u011f\u0131daki servisi olu\u015fturarak Angular ile Keycloak aras\u0131ndaki k\u00f6pr\u00fcy\u00fc olu\u015fturak temel ileti\u015fim servisini in\u015fa edelim:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Injectable } from '@angular\/core';\r\nimport Keycloak from 'keycloak-js';\r\n\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class KeycloakService {\r\n  static keycloak: Keycloak = new Keycloak({\r\n    url: 'http:\/\/127.0.0.1:8080\/',\r\n    realm: 'master',\r\n    clientId: 'angular-client',\r\n  });\r\n}\r\n<\/pre>\n<\/div>\n<p>Ard\u0131ndan Angular uygulamas\u0131nda kullan\u0131c\u0131y\u0131 g\u00fcvenli \u015fekilde do\u011frulamak ve ge\u00e7erli bir JWT \u00fcretebilmek i\u00e7in <em>app.config.ts<\/em> dosyas\u0131nda a\u015fa\u011f\u0131daki yap\u0131land\u0131rmada bulunmam\u0131z gerekmektedir:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { KeycloakService } from '.\/services\/keycloak.service.';\r\n\r\nexport const appConfig: ApplicationConfig = {\r\n  providers: &#x5B;\r\n    provideBrowserGlobalErrorListeners(),\r\n    provideRouter(routes),\r\n    provideAppInitializer(() =&gt; {\r\n      KeycloakService.keycloak.init({\r\n        onLoad: 'login-required',\r\n        pkceMethod: 'S256',\r\n        checkLoginIframe: false\r\n      })\r\n    }),\r\n    provideHttpClient()\r\n  ]\r\n};\r\n<\/pre>\n<\/div>\n<p><em>8<\/em> ile <em>12.<\/em> sat\u0131r aral\u0131\u011f\u0131ndaki yap\u0131land\u0131rma ile, SPA&#8217;n\u0131n Keycloak \u00fczerinden g\u00fcvenli \u015fekilde login olup JWT almas\u0131n\u0131 ve uygulaman\u0131n ancak bu kimlik do\u011fruland\u0131ktan sonra \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamaktay\u0131z.<\/p>\n<p>Burada;<\/p>\n<ul>\n<li>1\ufe0f\u20e3<code>onLoad: 'login-required'<\/code> ile login durumunu zorunlu k\u0131lmakta ve e\u011fer kullan\u0131c\u0131 login de\u011filse hi\u00e7 bekletmeksizin direkt Keycloak&#8217;a y\u00f6nlendirmenin ger\u00e7ekle\u015ftirilmesi gerekti\u011fini ifade etmekteyiz.\n<p>B\u00f6ylece uygulama a\u00e7\u0131s\u0131ndan en ba\u015ftan kimlik garanti alt\u0131na al\u0131nmaktad\u0131r.<\/p>\n<p>Buna alternatif olarak <code>onLoad: 'check-sso'<\/code> de\u011ferini verebilir ve login olunmad\u0131\u011f\u0131 taktirde sessiz kal\u0131nmas\u0131n\u0131 sa\u011flayabiliriz. \u00d6zellikle bu ayar public sayfalar i\u00e7in uygundur.\n<\/li>\n<li>2\ufe0f\u20e3<code>pkceMethod: 'S256'<\/code> ile bu SPA&#8217;n\u0131n authorization code flow&#8217;u PKCE ile kullanaca\u011f\u0131n\u0131 a\u00e7\u0131k\u00e7a belirtmekte ve PKCE&#8217;nin hangi y\u00f6ntemle hash&#8217;lenece\u011fini ifade etmekteyiz.\n<\/li>\n<li>3\ufe0f\u20e3<code>checkLoginIframe: false<\/code> ile de \u00f6nemli bir davran\u0131\u015f\u0131 yap\u0131land\u0131r\u0131yoruz. \u015e\u00f6yle ki; Keycloak belirli periyotlarda arka planda bir iframe a\u00e7makta ve bunun \u00fczerinden kullan\u0131c\u0131n\u0131n hala login olup olmad\u0131\u011f\u0131n\u0131 kontrol etmektedir. Bunu bizler g\u00f6remesek de browser g\u00f6rebilmektedir. Bizler bu yap\u0131land\u0131rma ile bu davran\u0131\u015f\u0131 y\u00f6netebilmekteyiz.\n<p><em>false<\/em> olarak ayarlayarak Keycloak&#8217;a o gizli iframe i\u015fini b\u0131rakmas\u0131 ve token s\u00fcresine bak\u0131laca\u011f\u0131n\u0131 ifade etmi\u015f oluyoruz.<\/li>\n<\/ul>\n<p>Evet, bu \u00e7al\u0131\u015fmalar sayesinde Angular uygulamas\u0131nda <code>\/authorize<\/code> endpoint&#8217;ine redirect i\u015flemini ger\u00e7ekle\u015ftirebilmekte, authorization code + PKCE ak\u0131\u015f\u0131n\u0131 y\u00f6netebilmekte, d\u00f6nen JWT&#8217;leri memory&#8217;de tutabilmekte, token s\u00fcresi dolunca sessizce refresh i\u015flemini ger\u00e7ekle\u015ftirebilmekte ve logout&#8217;ta <code>\/logout<\/code>&#8216;a y\u00f6nlendirmeyi sa\u011flayabilmekteyiz.\n<\/li>\n<li><em><strong>Ad\u0131m 5<\/strong> <span style=\"color:green;font-size:13px;\">(Token Alma)<\/span><\/em><br \/>\nBir \u00f6nceki ad\u0131mda <code>onLoad: 'login-required'<\/code> yap\u0131land\u0131rmas\u0131 ile uygulamada login s\u00f6z konusu de\u011filse Keycloak&#8217;a y\u00f6nlendirmesi gerekti\u011fi \u015feklinde bir konfig\u00fcrasyonda bulunmu\u015ftuk. Haliyle bu vaziyette uygulamay\u0131 derleyip aya\u011fa kald\u0131r\u0131rsak direkt Keycloak&#8217;a y\u00f6nlendirildi\u011fimizi g\u00f6receksiniz. Herhangi bir kullan\u0131c\u0131yla giri\u015f yap\u0131ld\u0131\u011f\u0131 taktirde art\u0131k token al\u0131nm\u0131\u015f ve login ger\u00e7ekle\u015ftirilmi\u015f olacakt\u0131r.<\/p>\n<p>Tabi burada dikkat edilmesi gereken noktalar vard\u0131r. \u015e\u00f6yle ki; elde edilen token <em>keycloak-js<\/em> taraf\u0131ndan ne localStorage&#8217;da, ne sessionStorage&#8217;da ne de cookie&#8217;de tutulmakta, yaln\u0131z SPA&#8217;n\u0131n JS memory&#8217;sinde tutulmaktad\u0131r. Ancak giri\u015f yap\u0131ld\u0131ktan sonra taray\u0131c\u0131n\u0131n cookie&#8217;lerine g\u00f6z atarsak orada baz\u0131 yap\u0131land\u0131rmalar\u0131 g\u00f6r\u00fcyor olaca\u011f\u0131z.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-6.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"764\" height=\"99\" class=\"aligncenter size-full wp-image-28428\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-6.png 764w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-6-300x39.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/a>Bu yap\u0131land\u0131rmalar token ile alakal\u0131 de\u011fildir. Bizzat Keycloak server cookie&#8217;leridir. Bunlar\u0131n SPA&#8217;da da g\u00f6z\u00fckmesinin sebebi kafan\u0131z\u0131 kar\u0131\u015ft\u0131rmas\u0131n&#8230; Hem SPA hem de Keycloak localhost&#8217;ta aya\u011fa kald\u0131r\u0131ld\u0131\u011f\u0131 i\u00e7in her ne kadar portlar\u0131 de\u011fi\u015fiyor olsa da bu domain&#8217;deki cookie&#8217;ler her iki tarafta da karman \u00e7orman g\u00f6z\u00fckmektedir.<\/p>\n<p>Ayr\u0131ca <a class=\"ez-toc-link ez-toc-heading-1\" href=\"#Browser_Flow_Authentication_Nedir\">Browser Flow Authentication Nedir?<\/a> ba\u015fl\u0131\u011f\u0131nda ele ald\u0131\u011f\u0131m\u0131z MVC y\u00f6ntemindeki gibi token, SPA \u00e7al\u0131\u015fmas\u0131nda cookie&#8217;e g\u00f6m\u00fclmemektedir.<\/p>\n<p>Velhas\u0131l&#8230;<\/p>\n<p>Evet, giri\u015f yap\u0131ld\u0131ktan ve token elde edildikten sonra a\u015fa\u011f\u0131daki gibi ula\u015f\u0131labilmektedir:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    KeycloakService.keycloak.token\r\n    KeycloakService.keycloak.refreshToken\r\n<\/pre>\n<\/div>\n<\/li>\n<li><em><strong>Ad\u0131m 6<\/strong> <span style=\"color:green;font-size:13px;\">(Asp.NET Core&#8217;da JWT Do\u011frulama ve \u00d6rnek Authorize \u0130\u015flemleri)<\/span><\/em><br \/>\nArt\u0131k Asp.NET Core&#8217;da JWT do\u011frulamay\u0131 sa\u011flayabilir ve Authorize edilmi\u015f bir endpoint \u00fczerinden testimizi ger\u00e7ekle\u015ftirebiliriz.<\/p>\n<div style=\"border:1px solid #e1e4e8;background:#f6f8fa;padding:16px;border-radius:8px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#24292e;word-break:break-all;\">\n  <strong style=\"display:block;margin-bottom:6px;color:#0969da;\">Gerekli K\u00fct\u00fcphaneler<\/strong><br \/>\n<a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.AspNetCore.Authentication.OpenIdConnect\" target=\"_blank\">Microsoft.AspNetCore.Authentication.OpenIdConnect<\/a>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\nbuilder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)\r\n                .AddJwtBearer(options =&gt;\r\n                {\r\n                    options.Authority = &quot;http:\/\/127.0.0.1:8080\/realms\/master&quot;;\r\n\r\n                    options.Audience = &quot;account&quot;;\r\n\r\n                    options.RequireHttpsMetadata = false;\r\n\r\n                    options.TokenValidationParameters = new TokenValidationParameters\r\n                    {\r\n                        ValidateIssuer = true,\r\n                        ValidateAudience = true,\r\n                        ValidateLifetime = true,\r\n                        ValidateIssuerSigningKey = true,\r\n                        NameClaimType = JwtRegisteredClaimNames.PreferredUsername\r\n                    };\r\n                });\r\n\r\nbuilder.Services.AddAuthorization();\r\n\r\nbuilder.Services.AddCors(options =&gt; options.AddDefaultPolicy(policy =&gt; policy.AllowAnyHeader()\r\n                                                                             .AllowAnyMethod()\r\n                                                                             .AllowAnyOrigin()));\r\n\r\n\r\nvar app = builder.Build();\r\n\r\napp.UseCors();\r\n\r\napp.UseAuthentication()\r\n   .UseAuthorization();\r\n\r\napp.MapGet(&quot;\/&quot;, () =&gt; TypedResults.Ok(&quot;Hello World!&quot;)).\r\n    RequireAuthorization();\r\n\r\napp.Run();\r\n<\/pre>\n<\/div>\n<\/li>\n<li><em><strong>Ad\u0131m 7<\/strong> <span style=\"color:green;font-size:13px;\">(Test Etme)<\/span><\/em><br \/>\nEvet, s\u0131ra t\u00fcm yapt\u0131\u011f\u0131m\u0131z \u00e7al\u0131\u015fmalar\u0131 test etmeye geldi diyebiliriz. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi basit bir component tasarlayal\u0131m ve testimizi ger\u00e7ekle\u015ftirelim:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n@Component({\r\n  selector: 'app-root',\r\n  imports: &#x5B;RouterOutlet],\r\n  template: `\r\n  &lt;h1&gt;{{ hi() }}&lt;\/h1&gt;\r\n\r\n  &lt;button (click)=&quot;getHelloWord()&quot;&gt;getHelloWord()&lt;\/button&gt;\r\n  `\r\n})\r\nexport class App {\r\n  httpClient: HttpClient = inject(HttpClient);\r\n\r\n  hi = signal(&quot;&quot;);\r\n  getHelloWord() {\r\n    this.httpClient.get(&quot;https:\/\/localhost:7297\/&quot;, {\r\n      headers: {\r\n        Authorization: `Bearer ${KeycloakService.keycloak.token}`\r\n      }\r\n    }).subscribe((res) =&gt; this.hi.set(res.toString()));\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-7.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"344\" height=\"142\" class=\"aligncenter size-full wp-image-28431\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-7.png 344w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-7-300x124.png 300w\" sizes=\"auto, (max-width: 344px) 100vw, 344px\" \/><\/a>\n<\/li>\n<\/ul>\n<p>\u0130\u015fte bu kadar \ud83d\ude42 \u00c7al\u0131\u015ft\u0131\u011f\u0131n\u0131z proje ister basit ister kurumsal \u00f6l\u00e7ekte olsun fark etmeksizin SPA&#8217;da Keycloak ile browser flow&#8217;u uygulamak sade ve sadece bu ad\u0131mlardan ibarettir.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Browser_Flowda_En_Cok_Yapilan_Hatalar\"><\/span>Browser Flow&#8217;da En \u00c7ok Yap\u0131lan Hatalar<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Son olarak browser flow&#8217;da dikkat edilmesi gereken hususlara &#8220;hata&#8221; orijinli bir bak\u0131\u015fla g\u00f6z atarak i\u00e7eri\u011fimizi nihayetlendirelim&#8230;<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong><em>OTP&#8217;yi <code>REQUIRED<\/code> yapmak<\/em><\/strong><br \/>\nKeycloak&#8217;da browser flow&#8217;da <em>-herkes 2FA kullans\u0131n ve g\u00fcvenlik arts\u0131n-<\/em> gerek\u00e7esiyle <em>OTP Form<\/em> <code>REQUIRED<\/code> olarak ayarlan\u0131rsa e\u011fer OTP&#8217;si olmayan kullan\u0131c\u0131lar login olamayacakt\u0131rlar!<\/p>\n<p><em>Neden mi?<\/em><br \/>\nOTP, kullan\u0131c\u0131n\u0131n Keycloak&#8217;ta tan\u0131ml\u0131 bir credential&#8217;\u0131d\u0131r. Haliyle browser flow&#8217;da OTP&#8217;nin <code>REQUIRED<\/code> olmas\u0131 durumunda, eski kullan\u0131c\u0131da OTP yoksa yahut yeni kullan\u0131c\u0131da OTP setup yap\u0131lmad\u0131ysa bu kullan\u0131c\u0131lar sistemin d\u0131\u015f\u0131nda b\u0131rak\u0131lacaklar\u0131ndan dolay\u0131 hi\u00e7bir zaman giri\u015f yapamayacakt\u0131rlar!<\/p>\n<p><em>Peki ne yap\u0131lmal\u0131?<\/em><br \/>\nOTP i\u00e7in do\u011fru model <code>CONDITIONAL<\/code> olarak tasarlanmas\u0131d\u0131r. Bu sayede, OTP&#8217;si olmayan ilk login s\u00fcrecinde OTP setup&#8217;a y\u00f6nlendirilecek, yok e\u011fer OTP&#8217;si varsa e\u011fer direkt OTP do\u011frulamaya y\u00f6nlendirilecektir. B\u00f6ylece ne eski kullan\u0131c\u0131 kilitlenecek, ne de yeni kullan\u0131c\u0131 zorla OTP&#8217;ye ge\u00e7irilecektir.\n<\/li>\n<li><strong><em>Cookie Authenticator&#8217;\u0131 silmek<\/em><\/strong><br \/>\n<em>-Zaten login oluyoruz, cookie&#8217;ye ne gerek var?-<\/em> d\u00fc\u015f\u00fcncesiyle Cookie authenticator&#8217;\u0131 silmeye \u00e7al\u0131\u015fmay\u0131n\u0131z. Cookie, ilgili taray\u0131c\u0131n\u0131n daha \u00f6nce login olup olmad\u0131\u011f\u0131n\u0131 kontrol etmektedir. B\u00f6ylece SSO ve session reuse gibi durumlar\u0131 y\u00fcr\u00fctmektedir.<\/p>\n<p>E\u011fer ki, cookie&#8217;yi silerseniz ayn\u0131 taray\u0131c\u0131da olsa dahi her request&#8217;te tekrar tekrar username \/ password isteyecektir ve SSO davran\u0131\u015f\u0131 sergilenemeyecektir. Bu da son kullan\u0131c\u0131 a\u00e7\u0131s\u0131ndan s\u00fcrekli <em>redirect loop<\/em> hissiyat\u0131 e\u015fli\u011finde <em>-niye her refresh&#8217;te login istiyor!-<\/em> isyan\u0131 do\u011furacakt\u0131r.<\/p>\n<\/li>\n<li><strong><em>Browser flow&#8217;u kopyalay\u0131p ba\u011flamamak<\/em><\/strong><br \/>\nBrowser flow&#8217;u duplicate edip kendinize g\u00f6re d\u00fczenleyebilirsiniz. Ama unutulmamal\u0131d\u0131r ki Keycloak&#8217;da default olan ak\u0131\u015f browser flow&#8217;dur. Haliyle sizlerin d\u00fczenledi\u011fi custom flow bind edilmedi\u011fi s\u00fcrece i\u015flevsellik g\u00f6stermeyecektir. Evet&#8230; flow olu\u015fturmak, kullanmak demek de\u011fildir. Bind edilmelidir.\n<\/li>\n<li><strong><em>Client Flow Override&#8217;\u0131 unutmak<\/em><\/strong><br \/>\nKeycloak&#8217;ta Authentication Flow&#8217;lar realm ve client olmak \u00fczere iki seviyede uygulan\u0131rlar. Varsay\u0131lan olarak realm seviyesi ge\u00e7erlidir. Yani aksi s\u00f6ylenmedi\u011fi s\u00fcrece ilgili realm \u00fczerinden login olan herkes o realm&#8217;deki kabul edilen flow&#8217;a g\u00f6re do\u011frulan\u0131p, yetkilendirilir.<\/p>\n<p>Ancak ger\u00e7ek hayatta \u015f\u00f6yle bir ihtiya\u00e7 s\u00f6z konusu olabilmektedir:<br \/>\n\u2192 Web uygulamas\u0131nda OTP olsun<br \/>\n\u2192 SPA&#8217;da OTP olmas\u0131n<br \/>\n\u2192 Admin UI&#8217;da farkl\u0131 kurallar olsun&#8230;<\/p>\n<p>Bu durumda realm seviyesinde tek bir browser flow&#8217;un olmas\u0131 s\u00fcre\u00e7 a\u00e7\u0131s\u0131ndan bir kriz gibi g\u00f6z\u00fckebilir. \u0130\u015fte bu taktirde bizler client seviyesinde flow override ger\u00e7ekle\u015ftirmeliyiz.<\/p>\n<p>Client flow override ile genel kural\u0131 bozarak client seviyesinde \u00f6zelle\u015ftirme yapabilmekteyiz.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3.png\" alt=\"Keycloak | Asp.NET Core \u0130le Browser Flow Authentication #7\" width=\"1608\" height=\"487\" class=\"aligncenter size-full wp-image-28421\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3.png 1608w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3-300x91.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3-1024x310.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3-768x233.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/02\/Keycloak-Asp.NET-Core-Ile-Browser-Flow-Authentication-7-3-1536x465.png 1536w\" sizes=\"auto, (max-width: 1608px) 100vw, 1608px\" \/><\/a>Bunun i\u00e7in yukar\u0131daki ekran al\u0131nt\u0131s\u0131nda g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <em style=\"font-size:12px;\">Clients \u2192 {Client} \u2192 Advanced \u2192 Authentication flow overrides<\/em> kombinasyonu takip edilmelidir.<\/p>\n<\/li>\n<li><strong><em>Authorization Code ile Direct Grant&#8217;i kar\u0131\u015ft\u0131rmak<\/em><\/strong><br \/>\nAuthorization Code ile Direct Grant&#8217;i kar\u0131\u015ft\u0131rmak olabilecek en kritik zihinsel hatalardan birisidir. Bu iki farkl\u0131 davran\u0131\u015f\u0131n do\u011fas\u0131nda a\u015fa\u011f\u0131daki mekanizmalar s\u00f6z konusudur.<\/p>\n<p>Authorization Code Low&#8217;da<\/p>\n<blockquote><p><em>Kullan\u0131c\u0131 taray\u0131c\u0131dan gelir, Keycloak sayfas\u0131na y\u00f6nlendirilir ve orada login olur.<\/em><\/p><\/blockquote>\n<p>Bu y\u00fczden \u015funlar m\u00fcmk\u00fcnd\u00fcr :<br \/>\n\u2192 Browser<br \/>\n\u2192 Redirect<br \/>\n\u2192 \/authorize<br \/>\n\u2192 \/signin-oidc<br \/>\n\u2192 Cookie<br \/>\n\u2192 SSO<br \/>\n\u2192 MFA<\/p>\n<p>Direct Grant &#8211; Resource Owner Password Credential Flow (ROPC)&#8217;da ise<\/p>\n<blockquote><p><em>Bir uygulama username &#038; password&#8217;\u00fc Keycloak&#8217;a REST API ile g\u00f6nderir ve \u00f6yle login sa\u011flar.<\/em><\/p><\/blockquote>\n<p>Dolay\u0131s\u0131yla burada<br \/>\n\u2192 Browser yok<br \/>\n\u2192 Redirect yok<br \/>\n\u2192 Cookie yok<br \/>\n\u2192 MFA s\u0131n\u0131rl\u0131<br \/>\n\u2192 ve kullan\u0131c\u0131 etkile\u015fimi yoktur!<\/p>\n<p>Sadece<br \/>\n\u2192 Username \/ Password<br \/>\n\u2192 API call<br \/>\nmevcuttur.<\/p>\n<p>Hata \u015furadad\u0131r ki, <em>-ben zaten token al\u0131yorum, her ikisinde de flow ayn\u0131-<\/em> diye d\u00fc\u015f\u00fcn\u00fclebilir.\n<\/li>\n<\/ul>\n<p>Nihai olarak;<br \/>\nBu i\u00e7erik boyunca, g\u00fcn\u00fcm\u00fczde en yayg\u0131n kimlik do\u011frulama yakla\u015f\u0131mlar\u0131ndan biri olan Keycloak Browser Flow yap\u0131s\u0131n\u0131 hem teorik arka plan\u0131yla ele ald\u0131k hem de pratikte s\u0131k\u00e7a kar\u015f\u0131la\u015f\u0131lan server-side web uygulamalar\u0131 (Asp.NET Core MVC) ve SPA tabanl\u0131 istemciler \u00fczerinden ger\u00e7ek kullan\u0131m senaryolar\u0131yla de\u011ferlendirdik. S\u00fcre\u00e7 i\u00e7erisinde Single Sign-On (SSO) mant\u0131\u011f\u0131n\u0131 anlamland\u0131rd\u0131k ve \u00e7oklu istemci bar\u0131nd\u0131ran mimarilerde kimlik do\u011frulama ak\u0131\u015flar\u0131 planlan\u0131rken nelere dikkat edilmesi gerekti\u011fine \u00f6zellikle odakland\u0131k. Bununla birlikte, Keycloak&#8217;un varsay\u0131lan olarak sundu\u011fu login ekran\u0131n\u0131n nas\u0131l \u00f6zelle\u015ftirilebilece\u011fini inceleyerek, hem kullan\u0131c\u0131 deneyimi hem de kurumsal ihtiya\u00e7lar a\u00e7\u0131s\u0131ndan nas\u0131l daha esnek \u00e7\u00f6z\u00fcmler \u00fcretilebilece\u011fini de ortaya koymu\u015f olduk.<\/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<div style=\"max-width:720px;margin:24px auto;padding:18px 20px;border-radius:12px;background:linear-gradient(135deg,#0d1117,#161b22);border:1px solid #30363d;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#e6edf3;box-shadow:0 10px 30px rgba(0,0,0,.35);\">\n<div style=\"display:flex;align-items:center;gap:14px;margin-bottom:12px;\">\n    <svg style=\"width:34px;height:34px;fill:#58a6ff;flex-shrink:0;\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n      <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.65 7.65 0 012-.27c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z\"><\/path>\n    <\/svg><\/p>\n<div>\n<div style=\"font-size:18px;font-weight:600;line-height:1.2;\">Repo Ad\u0131 Buraya<\/div>\n<div style=\"font-size:13px;color:#8b949e;\">https:\/\/github.com\/gncyyldz\/Keycloak.Examples<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div style=\"font-size:14px;line-height:1.6;color:#c9d1d9;margin-bottom:14px;\">\n    Bu repository, ilgili projenin kaynak kodlar\u0131n\u0131 ve mimari yap\u0131s\u0131n\u0131 i\u00e7ermektedir. Detaylar i\u00e7in GitHub \u00fczerinden inceleyebilirsiniz.\n  <\/div>\n<p>  <a href=\"https:\/\/github.com\/gncyyldz\/Keycloak.Examples\/tree\/Keycloak4.AspNetCore-%C4%B0le-Browser-Flow-Authentication\" target=\"_blank\" rel=\"noopener noreferrer\"\n     style=\"display:inline-block;padding:10px 16px;border-radius:8px;background:#238636;color:#ffffff;text-decoration:none;font-size:14px;font-weight:600;transition:all .2s ease;\"><br \/>\n    GitHub\u2019da G\u00f6r\u00fcnt\u00fcle \u2192<br \/>\n  <\/a><\/p>\n<\/div>\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, Bu i\u00e7eri\u011fimizde Asp.NET Core ile birlikte Keycloak&#8217;da Browser Flow Authentication konusunu hem teorik hem de pratik bir \u015fekilde netle\u015ftirebilece\u011fimiz bir incelemede bulunuyor olaca\u011f\u0131z. Browser Flow Authentication Nedir? Browser Flow, Keycloak&#8217;un taray\u0131c\u0131 tabanl\u0131 (interactive)&#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":28235,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5206,5554],"tags":[5657,2679,5646,3874,3872,5645,5644,5640,5648,5655,5656,5555,5658,5651,3833,5650,3959,5653,5654,5649,5652,5561,5562,5647],"class_list":["post-28401","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-keycloak","tag-ftl","tag-asp-net-core","tag-asp-net-core-browser-flow","tag-authorization-code","tag-authorization-code-flow","tag-browser-authentication","tag-browser-flow-authentication","tag-challenge","tag-coklu-oturum-acma","tag-direct-grant","tag-freemarker","tag-keycloak","tag-keycloak-js","tag-oidc","tag-openid-connect","tag-password-fatigue","tag-pkce","tag-resource-owner-password-credential-flow","tag-ropc","tag-sifre-yorgunlugu","tag-signout","tag-single-sign-on","tag-sso","tag-tek-oturum-acma"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28401","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=28401"}],"version-history":[{"count":14,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28401\/revisions"}],"predecessor-version":[{"id":28433,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28401\/revisions\/28433"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/28235"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=28401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=28401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=28401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}