﻿
{"id":28334,"date":"2026-01-29T08:03:02","date_gmt":"2026-01-29T08:03:02","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=28334"},"modified":"2026-01-29T08:03:02","modified_gmt":"2026-01-29T08:03:02","slug":"keycloakda-derinlemesine-kullanici-islemleri-4","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/","title":{"rendered":"Keycloak&#8217;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde; Keycloak platformunda kullan\u0131c\u0131 y\u00f6netimiyle ilgili s\u0131k kar\u015f\u0131la\u015f\u0131lan ancak genellikle y\u00fczeysel ge\u00e7ilen baz\u0131 ek senaryolara odaklan\u0131yor olaca\u011f\u0131z. Bu senaryolar; Keycloak&#8217;\u0131n varsay\u0131lan olarak sundu\u011fu kullan\u0131c\u0131 bilgilerine nas\u0131l ek alanlar eklenebilece\u011fi, kullan\u0131c\u0131lara ge\u00e7ici veya kal\u0131c\u0131 \u015fifrenin nas\u0131l tan\u0131mlanabilece\u011fi, <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/password-grant\/\" target=\"_blank\">Password Grant Type<\/a> \u00fczerinden kullan\u0131c\u0131 do\u011frulaman\u0131n nas\u0131l yap\u0131labilece\u011fi ve aktif oturum (session) bilgilerine nas\u0131l eri\u015filebilece\u011fi gibi s\u00fcre\u00e7leri kapsamaktad\u0131r&#8230; Ayr\u0131ca, bu s\u00fcre\u00e7ler s\u0131ras\u0131nda elde edilen token&#8217;lar\u0131 \u00e7\u00f6z\u00fcmleyerek detayl\u0131 bir \u015fekilde inceleyecek; token i\u00e7eri\u011fi \u00fczerinden userinfo endpoint&#8217;ine eri\u015ferek kullan\u0131c\u0131 bilgilerini nas\u0131l g\u00f6zlemleyebilece\u011fimizi de ele al\u0131yor olaca\u011f\u0131z. O halde haz\u0131rsan\u0131z ba\u015flayal\u0131m&#8230;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_88 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-5'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Client_Credentials_Ile_Clienti_Yetkilendirme\" >Client Credentials \u0130le Client&#8217;\u0131 Yetkilendirme<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Varsayilan_Olarak_Sunulan_Kullanici_Bilgilerine_Ek_Alan_Attribute_Ekleme\" >Varsay\u0131lan Olarak Sunulan Kullan\u0131c\u0131 Bilgilerine Ek Alan (Attribute) Ekleme<\/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\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Kullaniciya_Gecici_Temporary_ve_Kalici_Permanent_Sifre_Tanimlama\" >Kullan\u0131c\u0131ya Ge\u00e7ici (Temporary) ve Kal\u0131c\u0131 (Permanent) \u015eifre Tan\u0131mlama<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Password_Grant_Type_Ile_Kullaniciyi_Dogrulama\" >Password Grant Type \u0130le Kullan\u0131c\u0131y\u0131 Do\u011frulama<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Kullanicinin_Aktif_Oturum_Session_Bilgilerine_Erisme\" >Kullan\u0131c\u0131n\u0131n Aktif Oturum (Session) Bilgilerine Eri\u015fme<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#Access_Tokeni_Cozumleyelim\" >Access Token&#8217;\u0131 \u00c7\u00f6z\u00fcmleyelim<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-derinlemesine-kullanici-islemleri-4\/#UserInfo_Endpoint_ile_Kullanici_Bilgilerine_Erisim\" >UserInfo Endpoint ile Kullan\u0131c\u0131 Bilgilerine Eri\u015fim<\/a><\/li><\/ul><\/nav><\/div>\n<h5><span class=\"ez-toc-section\" id=\"Client_Credentials_Ile_Clienti_Yetkilendirme\"><\/span>Client Credentials \u0130le Client&#8217;\u0131 Yetkilendirme<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>T\u00fcm \u00e7al\u0131\u015fma s\u00fcrecinde kullanaca\u011f\u0131m\u0131z token, <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-ile-rest-api-uzerinden-temel-keycloak-islemleri-3\/\" target=\"_blank\">Asp.NET Core \u0130le REST API \u00dczerinden Temel Keycloak \u0130\u015flemleri #3<\/a> ba\u015fl\u0131kl\u0131 yaz\u0131m\u0131z\u0131n <em>&#8216;Client Credentials \u0130le Access Token Alma&#8217;<\/em> ba\u015fl\u0131\u011f\u0131 alt\u0131nda <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/client-credentials\/\" target=\"_blank\">client credentials<\/a> yakla\u015f\u0131m\u0131yla edindi\u011fimiz access token olacakt\u0131r. \u0130lgili \u00e7al\u0131\u015fmaya, i\u00e7eri\u011fimizin en sonunda verece\u011fimiz GitHub adresindeki projeden eri\u015febilir ve kullan\u0131m sa\u011flayabilirsiniz.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Varsayilan_Olarak_Sunulan_Kullanici_Bilgilerine_Ek_Alan_Attribute_Ekleme\"><\/span>Varsay\u0131lan Olarak Sunulan Kullan\u0131c\u0131 Bilgilerine Ek Alan (Attribute) Ekleme<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Keycloak&#8217;da bir kullan\u0131c\u0131 i\u00e7in varsay\u0131lan olarak <em>Username<\/em>, <em>Email<\/em>, <em>First Name<\/em> ve <em>Last Name<\/em> bilgileri sunulmaktad\u0131r. Bunlarla birlikte, bu alanlara ek olarak ihtiya\u00e7 do\u011frultusunda \u00f6zel (custom) alanlar tan\u0131mlamak da m\u00fcmk\u00fcnd\u00fcr. Bunun i\u00e7in yap\u0131lmas\u0131 gereken a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde oldu\u011fu gibi ilgili realm \u00fczerinden <span style=\"font-size:14px;\"><em>Realm settings<\/em> \u2794 <em>User profile<\/em> \u2794 <em>Create attribute<\/em><\/span> kombinasyonunu takip etmektir.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"1512\" height=\"637\" class=\"aligncenter size-full wp-image-28337\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png 1512w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-300x126.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1024x431.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-768x324.png 768w\" sizes=\"auto, (max-width: 1512px) 100vw, 1512px\" \/><\/a>Evet, Keycloak&#8217;da kullan\u0131c\u0131lara tan\u0131mlanan ek alanlara attribute denmektedir! Bir ba\u015fka deyi\u015fle, Keycloak&#8217;da standart alanlar\u0131n d\u0131\u015f\u0131ndaki her \u015feye \/ bilgiye kar\u015f\u0131l\u0131k gelen tan\u0131mlara attribute denmektedir. Bu kullan\u0131c\u0131larda <em>firstName<\/em>, <em>lastName<\/em> vs. gibi ekstradan alanlar olabilece\u011fi gibi bir realm&#8217;ler de genel konfig\u00fcrasyon ama\u00e7l\u0131 veya client&#8217;larda da \u00f6zel metadata tan\u0131mlama ama\u00e7l\u0131 alanlar olabilmektedir.<\/p>\n<blockquote><p><em>Keycloak&#8217;da attribute; standart alanlar\u0131n d\u0131\u015f\u0131nda her \u015feye \/ bilgiye kar\u015f\u0131l\u0131k gelen tan\u0131mlard\u0131r.<\/em><\/p><\/blockquote>\n<p>Bir attribute tan\u0131mlarken a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde olan alanlar\u0131n doldurulmas\u0131 gerekmektedir:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1.png\" alt=\"\" width=\"841\" height=\"724\" class=\"aligncenter size-full wp-image-28339\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1.png 841w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1-300x258.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-1-768x661.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><\/a>Burada a\u015fikar olanlar\u0131n d\u0131\u015f\u0131nda g\u00f6ze \u00e7arpan alanlar\u0131 izah etmekte fayda g\u00f6rmekteyim;<\/p>\n<ul style=\"font-size:14px;\">\n<li><em><u>Multivalued<\/u><\/em> : Tan\u0131mlanacak bu alanda birden fazla de\u011fer al\u0131nacaksa i\u015faretlenmelidir. \u0130\u015faretlendi\u011fi taktirde ilgili attribute bir array&#8217;e d\u00f6n\u00fc\u015fecektir.<\/li>\n<li><em><u>Attribute group<\/u><\/em> : Bu alan\u0131n profil ekran\u0131nda hangi ba\u015fl\u0131k alt\u0131nda g\u00f6r\u00fcnece\u011fini belirtir.<\/li>\n<li><em><u>Enabled when<\/u><\/em> : Bu attribute&#8217;un ne zaman devreye (yani token&#8217;a) girece\u011fi belirlenir. <em>Attribute her kullan\u0131c\u0131da m\u0131 \u00e7al\u0131\u015fs\u0131n, yoksa sadece istenirse mi \u00e7al\u0131\u015fs\u0131n?<\/em> ayar\u0131n\u0131 ger\u00e7ekle\u015ftirmemizi sa\u011flar. E\u011fer <em>Always<\/em> denirse, attribute her zaman aktif olacak ve token&#8217;a ko\u015fulsuz girecektir. Yok e\u011fer <em>Scope are requested<\/em> se\u00e7ilirse attribute ancak ilgili scope istendi\u011fi taktirde aktif olacak ve istenmedi\u011fi taktirde token&#8217;a girmeyecektir.<br \/>\nBu ayar\u0131n amac\u0131, token&#8217;\u0131n gereksiz yere \u015fi\u015fmesini ve bir yandan da veri if\u015fas\u0131n\u0131 \u00f6nlemektir.<\/li>\n<li><em><u>Required field<\/u><\/em> : Kullan\u0131c\u0131 login ya da register olurken bu alan\u0131n dolu olmas\u0131n\u0131n zorunlu olup olmamas\u0131n\u0131 ayarlar. Mesela, sonraki ad\u0131mlarda bahsi ge\u00e7ece\u011fi \u00fczere bir kullan\u0131c\u0131n\u0131n <em>firstname<\/em> ve <em>lastname<\/em> alanlar\u0131 bo\u015fsa e\u011fer login olunamayaca\u011f\u0131 durumu i\u015fte bu ayarla ili\u015fkilidir.<\/li>\n<li><em><u>Permission<\/u><\/em> : Alanla ilgili yetkilerin ayarland\u0131\u011f\u0131 b\u00f6l\u00fcmd\u00fcr:\n<ul>\n<li><em>Who can edit?<\/em> Bu alan\u0131;<br \/>\nUser \u2794 Kullan\u0131c\u0131 kendisi de\u011fi\u015ftirebilir.<br \/>\nAdmin \u2794 Sadece admin de\u011fi\u015ftirebilir.\n<\/li>\n<li><em>Who can view?<\/em> Bu alan\u0131;<br \/>\nUser \u2794 Kullan\u0131c\u0131 g\u00f6rebilir.<br \/>\nAdmin \u2794 Admin g\u00f6rebilir.\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u00d6rne\u011fin phone-number ad\u0131nda a\u015fa\u011f\u0131daki gibi bir attribute olu\u015ftural\u0131m.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-2.png\" alt=\"\" width=\"827\" height=\"614\" class=\"aligncenter size-full wp-image-28340\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-2.png 827w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-2-300x223.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-2-768x570.png 768w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/a>Tabi bu de\u011ferin bir telefon numaras\u0131 olup olmad\u0131\u011f\u0131n\u0131 kontrol edebilmek i\u00e7in bir validation tan\u0131mlamam\u0131z gerekmektedir. Bunu da a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi <em>Validations<\/em> alan\u0131ndan ekleyebiliriz:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-3.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"944\" height=\"362\" class=\"aligncenter size-full wp-image-28341\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-3.png 944w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-3-300x115.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-3-768x295.png 768w\" sizes=\"auto, (max-width: 944px) 100vw, 944px\" \/><\/a>E\u011fer ki bu validation&#8217;a uygun veri girilmezse Keycloak a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde oldu\u011fu gibi belirtilen error message&#8217;\u0131 d\u00f6nd\u00fcrecektir:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-4.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"586\" height=\"74\" class=\"aligncenter size-full wp-image-28342\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-4.png 586w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-4-300x38.png 300w\" sizes=\"auto, (max-width: 586px) 100vw, 586px\" \/><\/a>Velhas\u0131l, attribute sa\u011f salim tan\u0131mlanabildiyse e\u011fer kullan\u0131c\u0131 detaylar\u0131nda a\u015fa\u011f\u0131daki gibi g\u00f6z\u00fck\u00fcyor olacakt\u0131r:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-5.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"524\" height=\"273\" class=\"aligncenter size-full wp-image-28343\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-5.png 524w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-5-300x156.png 300w\" sizes=\"auto, (max-width: 524px) 100vw, 524px\" \/><\/a><strong>Peki t\u00fcm bu i\u015flemi Administration REST API \u00fczerinden nas\u0131l ger\u00e7ekle\u015ftirebiliriz?<\/strong><br \/>\nEvet, Keycloak&#8217;ta kullan\u0131c\u0131 bilgilerine ekstra alan eklemek aray\u00fczden olduk\u00e7a rahat. Ancak mevzu bahis programatik olarak bu i\u015fi ger\u00e7ekle\u015ftirmekse birazc\u0131k s\u00fcreci a\u015fa\u011f\u0131daki gibi detaya indirgememiz gerekmektedir:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPost(&quot;\/realm\/{realm}\/configure-user-attributes&quot;, async (string realm, TokenRequestService tokenRequestService, IHttpClientFactory httpClientFactory, RealmAttributeConfigRequest request) =&gt;\r\n{\r\n    var token = await tokenRequestService.GetAccessTokenAsync();\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, token.AccessToken);\r\n\r\n    \/\/ 1. Mevcut User Profile yap\u0131land\u0131rmas\u0131n\u0131 al\r\n    var getProfileResponse = await httpClient.GetAsync($&quot;\/admin\/realms\/{realm}\/users\/profile&quot;);\r\n\r\n    if (!getProfileResponse.IsSuccessStatusCode)\r\n        return Results.BadRequest(new { error = &quot;User Profile yap\u0131land\u0131rmas\u0131 al\u0131namad\u0131!&quot; });\r\n\r\n    var profileContent = await getProfileResponse.Content.ReadAsStringAsync();\r\n    var existingProfile = JsonSerializer.Deserialize&lt;JsonElement&gt;(profileContent);\r\n\r\n    \/\/ 2. Mevcut attributes listesini al\r\n    List&lt;object&gt; attributesList = null;\r\n\r\n    if (existingProfile.TryGetProperty(&quot;attributes&quot;, out var attributesElement))\r\n        attributesList = attributesElement\r\n                    .EnumerateArray()\r\n                    .Select(attr =&gt; JsonSerializer.Deserialize&lt;object&gt;(attr.GetRawText()))\r\n                    .OfType&lt;object&gt;()\r\n                    .ToList();\r\n\r\n    \/\/ 3. Yeni attribute'lar\u0131 ekle\r\n    request.NewAttributes.ForEach(newAttribute =&gt;\r\n    {\r\n        \/\/ Validation objesini olu\u015ftur\r\n        var validations = new Dictionary&lt;string, object&gt;();\r\n\r\n        if (newAttribute.Validations is not null)\r\n            newAttribute.Validations.ForEach(validation =&gt;\r\n            {\r\n                validations&#x5B;validation.Type.ToLower()] = validation.Type.ToLower() switch\r\n                {\r\n                    &quot;length&quot; =&gt; new { min = validation.Min, max = validation.Max },\r\n                    &quot;email&quot; =&gt; new { },\r\n                    &quot;pattern&quot; =&gt; new { pattern = validation.Pattern, errorMessage = validation.ErrorMessage ?? &quot;Ge\u00e7ersiz format&quot; },\r\n                    &quot;options&quot; =&gt; new { options = validation.Options },\r\n                    &quot;uri&quot; =&gt; new { },\r\n                    &quot;integer&quot; =&gt; new { min = validation.Min, max = validation.Max },\r\n                    &quot;number&quot; =&gt; new { min = validation.Min, max = validation.Max }\r\n                };\r\n            });\r\n\r\n        var attributeConfig = new Dictionary&lt;string, object&gt;\r\n        {\r\n            &#x5B;&quot;name&quot;] = newAttribute.Name,\r\n            &#x5B;&quot;displayName&quot;] = newAttribute.DisplayName ?? newAttribute.Name,\r\n            &#x5B;&quot;validations&quot;] = validations,\r\n            &#x5B;&quot;permissions&quot;] = new\r\n            {\r\n                view = new&#x5B;] { &quot;admin&quot;, &quot;user&quot; },\r\n                edit = new&#x5B;] { &quot;admin&quot;, &quot;user&quot; }\r\n            },\r\n            &#x5B;&quot;multivalued&quot;] = newAttribute.Multivalued\r\n        };\r\n\r\n        \/\/ Required sadece true oldu\u011funda ekle\r\n        if (newAttribute.Required)\r\n            attributeConfig&#x5B;&quot;required&quot;] = new\r\n            {\r\n                roles = new&#x5B;] { &quot;user&quot; }\r\n            };\r\n\r\n        attributesList!.Add(attributeConfig);\r\n    });\r\n\r\n    \/\/ 4. G\u00fcncellenmi\u015f profile yap\u0131land\u0131rmas\u0131n\u0131 haz\u0131rla\r\n    var updatedProfile = new\r\n    {\r\n        attributes = attributesList,\r\n        groups = existingProfile.TryGetProperty(&quot;groups&quot;, out var groups) ? JsonSerializer.Deserialize&lt;object&gt;(groups.GetRawText()) : new { }\r\n    };\r\n\r\n    var updateJson = JsonSerializer.Serialize(updatedProfile);\r\n    var updateRequest = new StringContent(updateJson, Encoding.UTF8, MediaTypeNames.Application.Json);\r\n\r\n    \/\/ 5. User Profile'\u0131 g\u00fcncelle\r\n    var updateResponse = await httpClient.PutAsync($&quot;\/admin\/realms\/{realm}\/users\/profile&quot;, updateRequest);\r\n\r\n    if (updateResponse.IsSuccessStatusCode)\r\n        return Results.Ok(new { message = $&quot;Realm seviyesinde {request.NewAttributes.Count} adet yeni attribute ba\u015far\u0131yla tan\u0131mland\u0131!&quot; });\r\n\r\n    var errorContent = await updateResponse.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<p>Burada dikkat edilmesi gereken husus \u015fudur ki; attribute&#8217;larla ilgili bir \u00e7al\u0131\u015fma yap\u0131yorsak e\u011fer \u00f6nceki attribute&#8217;lar\u0131n hepsini elde edip o \u015fekilde \u00e7al\u0131\u015fma sergilenmesi gerekti\u011fidir. Haliyle bu mant\u0131kla yukar\u0131daki kodu de\u011ferlendirdi\u011fimizde <em>9<\/em> ile <em>25.<\/em> sat\u0131r aral\u0131\u011f\u0131nda mevcut <em>User Profile<\/em> yap\u0131land\u0131rmas\u0131 elde edilmekte ve <em>28<\/em> ile <em>69.<\/em> sat\u0131r aral\u0131\u011f\u0131nda bu mevcut attribute&#8217;larla birlikte yenileri eklenerek Keycloak&#8217;a g\u00f6nderilmektedir&#8230;<\/p>\n<p><em>31<\/em> ile <em>46.<\/em> sat\u0131rda ise yeni eklenen attribute&#8217;un varsa validation davran\u0131\u015f\u0131 tespit edilmekte ve <em>48<\/em> ile <em>68.<\/em> sat\u0131r aral\u0131\u011f\u0131nda ise bu attribute&#8217;da (varsa) validation ayarlar\u0131 ile birlikte mevcut attribute&#8217;lar\u0131n aras\u0131na eklenerek Keycloak&#8217;a g\u00f6nderilmeye haz\u0131r bir hale gelinmektedir.<\/p>\n<p><em>72<\/em> ile <em>76.<\/em> sat\u0131r aral\u0131\u011f\u0131nda ise <em>User Profile<\/em>&#8216;\u0131 g\u00fcncelleyecek formatta <span style=\"font-size:14px;\">(i\u00e7erisinde attribute&#8217;lar\u0131n en son hali ve group bilgisi e\u015fli\u011finde)<\/span> nesne haz\u0131rlanmakta ve <em>82.<\/em> sat\u0131rda bu nesne <code>\/admin\/realms\/{realm}\/users\/profile<\/code> endpoint&#8217;ine g\u00f6nderilerek t\u00fcm \u00e7al\u0131\u015fma ba\u015far\u0131yla nihayete erdirilmektedir.<\/p>\n<p>\u0130\u015fte biraz \u00f6nce aray\u00fcz \u00fczerinden yapt\u0131\u011f\u0131m\u0131z yap\u0131land\u0131rman\u0131n kodsal kar\u015f\u0131l\u0131\u011f\u0131 birebir bu \u015fekildedir. Tabi burada <em>permissions<\/em> yap\u0131land\u0131rmas\u0131n\u0131 da client&#8217;tan bekleyebilir ve daha opsiyonel bir hale getirebiliriz. Buras\u0131n\u0131 sabit de\u011ferlerle b\u0131rak\u0131yor ve gerisini sizlere b\u0131rak\u0131yorum art\u0131k&#8230;<\/p>\n<p>Bu endpoint&#8217;te beklenen body a\u015fa\u011f\u0131daki gibi olacakt\u0131r:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;newAttributes&quot;: &#x5B;\r\n    {\r\n      &quot;name&quot;: &quot;phone-number&quot;,\r\n      &quot;displayName&quot;: &quot;Phone Number&quot;,\r\n      &quot;multivalued&quot;: false,\r\n      &quot;required&quot;: false,\r\n      &quot;validations&quot;: &#x5B;\r\n        {\r\n          &quot;type&quot;: &quot;pattern&quot;,\r\n          &quot;pattern&quot;: &quot;^0\\\\s\\\\(&#x5B;5]&#x5B;0-9]{2}\\\\)\\\\s&#x5B;0-9]{3}\\\\s&#x5B;0-9]{2}\\\\s&#x5B;0-9]{2}$&quot;,\r\n          &quot;errorMessage&quot;: &quot;L\u00fctfen telefon numaras\u0131n\u0131 do\u011fru giriniz.&quot;,\r\n          &quot;options&quot;: &#x5B;\r\n            &quot;&quot;\r\n          ]\r\n        }\r\n      ]\r\n    }\r\n  ]\r\n}\r\n<\/pre>\n<\/div>\n<p><strong>Peki bir kullan\u0131c\u0131daki attribute de\u011ferini nas\u0131l de\u011fi\u015ftirebiliriz?<\/strong><br \/>\nBunun i\u00e7in de yap\u0131lmas\u0131 gereken \u00f6nce kullan\u0131c\u0131y\u0131 elde edip, yine mevcut attribute&#8217;lar\u0131 e\u015fli\u011finde, g\u00fcncellenecek attribute de\u011ferini g\u00f6ndermek&#8230;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPut(&quot;\/user\/{userId}\/add-new-attribute\/{realm}&quot;, async (string userId, string realm, TokenRequestService tokenRequestService, IHttpClientFactory httpClientFactory, AddAttributeRequest request) =&gt;\r\n{\r\n    var token = await tokenRequestService.GetAccessTokenAsync();\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, token.AccessToken);\r\n\r\n    \/\/ 1. Mevcut kullan\u0131c\u0131y\u0131 GET ile \u00e7ek\r\n    var getUserResponse = await httpClient.GetAsync($&quot;\/admin\/realms\/{realm}\/users\/{userId}&quot;);\r\n\r\n    if (!getUserResponse.IsSuccessStatusCode)\r\n        return Results.NotFound(new { error = &quot;Kullan\u0131c\u0131 bulunamad\u0131!&quot; });\r\n\r\n    var userContent = await getUserResponse.Content.ReadAsStringAsync();\r\n    var existingUser = JsonSerializer.Deserialize&lt;JsonElement&gt;(userContent);\r\n\r\n    \/\/ 2. Mevcut attributes'lar\u0131 al\r\n    var existingAttributes = new Dictionary&lt;string, List&lt;string&gt;&gt;();\r\n\r\n    if (existingUser.TryGetProperty(&quot;attributes&quot;, out var attributesElement))\r\n        attributesElement\r\n            .EnumerateObject()\r\n            .Select(attribute =&gt; existingAttributes&#x5B;attribute.Name] = attribute.Value\r\n                                        .EnumerateArray()\r\n                                        .Select(v =&gt; v.GetString() ?? string.Empty)\r\n                                        .ToList());\r\n\r\n    \/\/ 3. Yeni attribute'lar\u0131 mevcut olanlara ekle\r\n    request.NewAttributes.ToList().ForEach(newAttribute =&gt; existingAttributes&#x5B;newAttribute.Key] = newAttribute.Value);\r\n\r\n    \/\/ 4. Kullan\u0131c\u0131y\u0131 g\u00fcncelle (t\u00fcm attributes ile birlikte)\r\n    var updateUser = new\r\n    {\r\n        firstName = existingUser.GetProperty(&quot;firstName&quot;).GetString(),\r\n        lastName = existingUser.GetProperty(&quot;lastName&quot;).GetString(),\r\n        email = existingUser.GetProperty(&quot;email&quot;).GetString(),\r\n        enabled = existingUser.GetProperty(&quot;enabled&quot;).GetBoolean(),\r\n        attributes = existingAttributes\r\n    };\r\n\r\n    var updateJson = JsonSerializer.Serialize(updateUser);\r\n    var updateRequest = new StringContent(updateJson, Encoding.UTF8, MediaTypeNames.Application.Json);\r\n\r\n    var updateResponse = await httpClient.PutAsync($&quot;\/admin\/realms\/{realm}\/users\/{userId}&quot;, updateRequest);\r\n\r\n    if (updateResponse.IsSuccessStatusCode)\r\n        return Results.Ok(new { message = &quot;Yeni attribute'lar ba\u015far\u0131yla eklendi, mevcut olanlar korundu!&quot; });\r\n\r\n    var errorContent = await updateResponse.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<p>Kodu incelerseniz e\u011fer; <em>18<\/em> ile <em>26.<\/em> sat\u0131r aral\u0131\u011f\u0131nda mevcut t\u00fcm attribute&#8217;lar \u00e7ekilmekte, <em>29.<\/em> sat\u0131rda ise g\u00fcncellenen attribute&#8217;lar body&#8217;den ay\u0131klanarak mevcutlar\u0131n de\u011ferleriyle de\u011fi\u015ftirilmektedir. Ard\u0131ndan <em>32<\/em> ile <em>39.<\/em> sat\u0131r aral\u0131\u011f\u0131nda mevcut olanlarla birlikte t\u00fcm attribute&#8217;lar en g\u00fcncel halleriyle nesneye d\u00f6n\u00fc\u015ft\u00fcr\u00fclmekte ve <em>44.<\/em> sat\u0131rda da <code>\/admin\/realms\/{realm}\/users\/{userId}<\/code> endpoint&#8217;ine g\u00f6nderilerek g\u00fcncelleme sa\u011flanmaktad\u0131r.<\/p>\n<p>Bu attribute g\u00fcncelleme s\u00fcrecinde de body a\u015fa\u011f\u0131daki gibi olacakt\u0131r:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;newAttributes&quot;: {\r\n    &quot;phone-number&quot;: &#x5B;\r\n      &quot;0 (507) 751 45 93&quot;\r\n    ]\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p><strong>Peki bir kullan\u0131c\u0131 eklenirken attribute de\u011ferleriyle birlikte nas\u0131l eklenebilir?<\/strong><br \/>\nMant\u0131k ayn\u0131:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPost(&quot;\/user\/add-attributes\/{realm}&quot;, async (string realm, TokenRequestService tokenRequestService, IHttpClientFactory httpClientFactory, UserRequest request) =&gt;\r\n{\r\n    var token = await tokenRequestService.GetAccessTokenAsync();\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    var user = new\r\n    {\r\n        username = request.Username,\r\n        email = request.Email,\r\n        enabled = request.Enabled,\r\n        firstName = request.FirstName,\r\n        lastName = request.LastName,\r\n        attributes = request.CustomAttributes\r\n    };\r\n\r\n    var userJson = JsonSerializer.Serialize(user);\r\n    var userRequest = new StringContent(userJson, Encoding.UTF8, MediaTypeNames.Application.Json);\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, token.AccessToken);\r\n\r\n    var response = await httpClient.PostAsync($&quot;\/admin\/realms\/{realm}\/users&quot;, userRequest);\r\n\r\n    if (response.IsSuccessStatusCode)\r\n        return Results.Ok(new { message = &quot;Kullan\u0131c\u0131 ba\u015far\u0131yla olu\u015fturuldu ve \u00f6zel alanlar eklendi!&quot; });\r\n\r\n    var errorContent = await response.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<p>Kullan\u0131c\u0131 olu\u015fturulurken <em>User profile<\/em>&#8216;daki ekstradan tan\u0131mlanm\u0131\u015f olan attribute&#8217;lara de\u011fer g\u00f6nderebilmek i\u00e7in yukar\u0131daki gibi bir \u00e7al\u0131\u015fma yap\u0131lmas\u0131 gayet yeterlidir. Misal olarak bu endpoint&#8217;e a\u015fa\u011f\u0131daki body&#8217;de bir istekte bulunulursa &#8216;xyz&#8217; kullan\u0131c\u0131s\u0131 olu\u015fturulurken belirtilen telefon numaras\u0131yla olu\u015fturulacakt\u0131r:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;username&quot;: &quot;xyz&quot;,\r\n  &quot;enabled&quot;: true,\r\n  &quot;email&quot;: &quot;xyz@gmail.com&quot;,\r\n  &quot;emailVerified&quot;: true,\r\n  &quot;firstName&quot;: &quot;Xyz&quot;,\r\n  &quot;lastName&quot;: &quot;Zyx&quot;,\r\n  &quot;customAttributes&quot;: {\r\n    &quot;phone-number&quot;: &#x5B;\r\n      &quot;0 (507) 751 45 92&quot;\r\n    ]\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<h5><span class=\"ez-toc-section\" id=\"Kullaniciya_Gecici_Temporary_ve_Kalici_Permanent_Sifre_Tanimlama\"><\/span>Kullan\u0131c\u0131ya Ge\u00e7ici (Temporary) ve Kal\u0131c\u0131 (Permanent) \u015eifre Tan\u0131mlama<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Keycloak&#8217;da kullan\u0131c\u0131 \u015fifrelerini tan\u0131mlarken ge\u00e7ici (temporary) ve kal\u0131c\u0131 (permanent) ayr\u0131m\u0131, temel olarak g\u00fcvenlik ve kullan\u0131c\u0131 y\u00f6netimi politikalar\u0131n\u0131 desteklemek amac\u0131yla varl\u0131k g\u00f6stermektedir. Bu ayr\u0131m, kullan\u0131c\u0131lara <code>admin<\/code> taraf\u0131ndan verilen ba\u015flang\u0131\u00e7 \u015fifrelerinin kal\u0131c\u0131 olarak kullanmas\u0131n\u0131 \u00f6nleyerek, daha g\u00fcvenli bir kimlik do\u011frulama s\u00fcreci sa\u011flamaktad\u0131r. Ge\u00e7ici \u015fifre, kullan\u0131c\u0131y\u0131 ilk giri\u015fte \u015fifre de\u011fi\u015ftirmeye zorlayarak, e-posta gibi g\u00fcvensiz kanallardan \u015fifre payla\u015f\u0131m\u0131 gibi potansiyel g\u00fcvenlik risklerine kar\u015f\u0131 korumaktad\u0131r. Kal\u0131c\u0131 \u015fifre ise, do\u011frudan uzun vadeli kullan\u0131m i\u00e7in ayarlanmakta ve zorunlu de\u011fi\u015fiklik gerektirmemektedir.<\/p>\n<p>Keycloak&#8217;da ge\u00e7ici \u015fifre tan\u0131mlanm\u0131\u015f bir kullan\u0131c\u0131 ilk giri\u015f yapt\u0131\u011f\u0131nda Keycloak taraf\u0131ndan otomatik bir \u015fekilde \u015fifre g\u00fcncellemeye y\u00f6nlendirilecek ve yeni \u015fifre girilmedi\u011fi taktirde oturum a\u00e7\u0131m\u0131na izin verilmeyecektir.<\/p>\n<p>Keycloak&#8217;da \u015fifre de\u011fi\u015fimini ger\u00e7ekle\u015ftirebilmek i\u00e7in a\u015fa\u011f\u0131daki endpoint&#8217;e <em>PUT<\/em> iste\u011finde bulunmak gerekmektedir:<\/p>\n<div style=\"background: #0f172a;color: #38bdf8;padding: 16px 20px;border-radius: 12px;font-family: system-ui, -apple-system, sans-serif;border: 1px solid #334155;margin: 1.2em 0;box-shadow: 0 4px 15px rgba(0,0,0,0.25);text-decoration: none;font-weight: 500;word-break: break-all;transition: color 0.2s;\">\n    <strong style=\"color:#60a5fa;font-size:15px;\">\ud83d\udd17 PUT \/admin\/realms\/{realm}\/users\/{userId}\/reset-password<br \/>\n<\/strong>\n<\/div>\n<p>Body:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;type&quot;: &quot;password&quot;,\r\n  &quot;value&quot;: string,\r\n  &quot;temporary&quot;: boolean\r\n}\r\n<\/pre>\n<\/div>\n<p>\u0130stekte a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirilebilir:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPut(&quot;\/user\/{userId}\/reset-password\/{realm}&quot;, async (string userId, string realm, TokenRequestService tokenRequestService, IHttpClientFactory httpClientFactory, SetPasswordRequest request) =&gt;\r\n{\r\n    var token = await tokenRequestService.GetAccessTokenAsync();\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, token.AccessToken);\r\n\r\n    var passwordData = new\r\n    {\r\n        type = &quot;password&quot;,\r\n        value = request.Password,\r\n        temporary = request.IsTemporary\r\n    };\r\n\r\n    var passwordJson = JsonSerializer.Serialize(passwordData);\r\n    var passwordRequest = new StringContent(passwordJson, Encoding.UTF8, MediaTypeNames.Application.Json);\r\n\r\n    var response = await httpClient.PutAsync($&quot;\/admin\/realms\/{realm}\/users\/{userId}\/reset-password&quot;, passwordRequest);\r\n\r\n    if (response.IsSuccessStatusCode)\r\n        return Results.Ok(new { message = $&quot;\u015eifre ba\u015far\u0131yla {(request.IsTemporary ? &quot;ge\u00e7ici&quot; : &quot;kal\u0131c\u0131&quot;)} olarak ayarland\u0131!&quot; });\r\n\r\n    var errorContent = await response.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<h5><span class=\"ez-toc-section\" id=\"Password_Grant_Type_Ile_Kullaniciyi_Dogrulama\"><\/span>Password Grant Type \u0130le Kullan\u0131c\u0131y\u0131 Do\u011frulama<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Password Grant Type <em>(Resource Owner Password Credentials Grant)<\/em>, OAuth 2.0&#8217;da en tart\u0131\u015fmal\u0131 ve en az tavsiye edilen ak\u0131\u015f t\u00fcr\u00fc olsa da maalesef hala \u00e7ok yayg\u0131n kullan\u0131lmakta oldu\u011fu i\u00e7in bilinmesi kritik arz eden bir davran\u0131\u015fa sahiptir.<\/p>\n<blockquote><p><em>Password Grant&#8217;da; client&#8217;\u0131n kullan\u0131c\u0131 bilgilerini (username &#038; password) bildi\u011fi \/ ald\u0131\u011f\u0131 tek grant tipidir.<\/em><\/p><\/blockquote>\n<p>Bu ak\u0131\u015f tipinde login i\u015flemini ger\u00e7ekle\u015ftirebilmek i\u00e7in \u00f6ncelikle a\u015fa\u011f\u0131daki endpoint&#8217;e verilen \u00f6rnek \u00e7al\u0131\u015fmadaki gibi bir i\u00e7erikle <em>POST<\/em> iste\u011finde bulunulmas\u0131 gerekmektedir:<\/p>\n<div style=\"background: #0f172a;color: #38bdf8;padding: 16px 20px;border-radius: 12px;font-family: system-ui, -apple-system, sans-serif;border: 1px solid #334155;margin: 1.2em 0;box-shadow: 0 4px 15px rgba(0,0,0,0.25);text-decoration: none;font-weight: 500;word-break: break-all;transition: color 0.2s;\">\n    <strong style=\"color:#60a5fa;font-size:15px;\">\ud83d\udd17 POST \/realms\/{realm}\/protocol\/openid-connect\/token<br \/>\n<\/strong>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPost(&quot;\/user\/authenticate\/{realm}&quot;, async (string realm, IHttpClientFactory httpClientFactory, PasswordGrantRequest request) =&gt;\r\n{\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    var formData = new Dictionary&lt;string, string&gt;\r\n    {\r\n        &#x5B;&quot;grant_type&quot;] = &quot;password&quot;,\r\n        &#x5B;&quot;client_id&quot;] = request.ClientId,\r\n        &#x5B;&quot;username&quot;] = request.Username,\r\n        &#x5B;&quot;password&quot;] = request.Password\r\n    };\r\n\r\n    if (!string.IsNullOrEmpty(request.ClientSecret))\r\n        formData&#x5B;&quot;client_secret&quot;] = request.ClientSecret;\r\n\r\n    if (!string.IsNullOrEmpty(request.Scope))\r\n        formData&#x5B;&quot;scope&quot;] = request.Scope;\r\n\r\n    var formContent = new FormUrlEncodedContent(formData);\r\n\r\n    var response = await httpClient.PostAsync($&quot;\/realms\/{realm}\/protocol\/openid-connect\/token&quot;, formContent);\r\n\r\n    if (response.IsSuccessStatusCode)\r\n    {\r\n        var tokenContent = await response.Content.ReadAsStringAsync();\r\n        var tokenResponse = JsonSerializer.Deserialize&lt;JsonElement&gt;(tokenContent);\r\n\r\n        return Results.Ok(new\r\n        {\r\n            accessToken = tokenResponse.GetProperty(&quot;access_token&quot;).GetString(),\r\n            refreshToken = tokenResponse.TryGetProperty(&quot;refresh_token&quot;, out var rt) ? rt.GetString() : null,\r\n            expiresIn = tokenResponse.GetProperty(&quot;expires_in&quot;).GetInt32(),\r\n            tokenType = tokenResponse.GetProperty(&quot;token_type&quot;).GetString()\r\n        });\r\n    }\r\n\r\n    var errorContent = await response.Content.ReadAsStringAsync();\r\n    return Results.Unauthorized();\r\n});\r\n<\/pre>\n<\/div>\n<p>Bu ak\u0131\u015fta dikkat edilmesi gereken iki husus mevcuttur, biri; hangi client \u00fczerinden kullan\u0131c\u0131 ad\u0131 ve \u015fifreyle bir token talebinde bulunulacaksa, o client&#8217;\u0131n <em>Direct access grants<\/em> authentication flow&#8217;u desteklemesi gereklili\u011fidir. Di\u011feri ise ilgili kullan\u0131c\u0131n\u0131n \u015fifresinin ge\u00e7ici olmamas\u0131 durumudur! Aksi taktirde token talebi ba\u015far\u0131l\u0131 olmayacakt\u0131r.<\/p>\n<p>Ayr\u0131ca kodu incelerseniz <code>client_secret<\/code> de\u011ferinin opsiyonel oldu\u011funu g\u00f6receksiniz. Bu client&#8217;\u0131n access type&#8217;\u0131na g\u00f6re de\u011fi\u015fiklik g\u00f6sterebilece\u011fi i\u00e7in opsiyonel yap\u0131lm\u0131\u015f bir de\u011ferdir. E\u011fer ki client; SPA&#8217;ler ya da mobile application&#8217;lar gibi public client ise bu t\u00fcr uygulamalarda client secret g\u00fcvenli bir \u015fekilde saklanamayaca\u011f\u0131 i\u00e7in haliyle secret de\u011feri olmaks\u0131z\u0131n bir \u00e7al\u0131\u015fma s\u00f6z konusu olacakt\u0131r. Yok e\u011fer backend API&#8217;ler yahut server-side web application&#8217;lar gibi <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/confidential-client\/\" target=\"_blank\">confidential client<\/a> ise bu tarz uygulamalar\u0131n g\u00fcvenli sunucu ortam\u0131nda \u00e7al\u0131\u015fmas\u0131ndan kaynakl\u0131 secret de\u011feri g\u00fcvenle saklanabilece\u011finden, secret de\u011feriyle \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirilecektir.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Kullanicinin_Aktif_Oturum_Session_Bilgilerine_Erisme\"><\/span>Kullan\u0131c\u0131n\u0131n Aktif Oturum (Session) Bilgilerine Eri\u015fme<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Bir kullan\u0131c\u0131n\u0131n aktif oturum bilgilerini elde edebilmek i\u00e7in a\u015fa\u011f\u0131daki endpoint&#8217;e <em>GET<\/em> iste\u011finde bulunulmas\u0131 yeterlidir:<\/p>\n<div style=\"background: #0f172a;color: #38bdf8;padding: 16px 20px;border-radius: 12px;font-family: system-ui, -apple-system, sans-serif;border: 1px solid #334155;margin: 1.2em 0;box-shadow: 0 4px 15px rgba(0,0,0,0.25);text-decoration: none;font-weight: 500;word-break: break-all;transition: color 0.2s;\">\n    <strong style=\"color:#60a5fa;font-size:15px;\">\ud83d\udd17 GET \/admin\/realms\/{realm}\/users\/{userId}\/sessions<br \/>\n<\/strong>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/user\/{userId}\/sessions\/{realm}&quot;, async (string userId, string realm, TokenRequestService tokenRequestService, IHttpClientFactory httpClientFactory) =&gt;\r\n{\r\n    var token = await tokenRequestService.GetAccessTokenAsync();\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, token.AccessToken);\r\n\r\n    var response = await httpClient.GetAsync($&quot;\/admin\/realms\/{realm}\/users\/{userId}\/sessions&quot;);\r\n\r\n    if (response.IsSuccessStatusCode)\r\n    {\r\n        var sessionsContent = await response.Content.ReadAsStringAsync();\r\n        var sessions = JsonSerializer.Deserialize&lt;JsonElement&gt;(sessionsContent);\r\n\r\n        return Results.Ok(new\r\n        {\r\n            userId,\r\n            activeSessions = sessions.EnumerateArray().Select(session =&gt; new\r\n            {\r\n                id = session.GetProperty(&quot;id&quot;).GetString(),\r\n                username = session.TryGetProperty(&quot;username&quot;, out var un) ? un.GetString() : null,\r\n                ipAddress = session.TryGetProperty(&quot;ipAddress&quot;, out var ip) ? ip.GetString() : null,\r\n                start = session.TryGetProperty(&quot;start&quot;, out var st) ? DateTimeOffset.FromUnixTimeMilliseconds(st.GetInt64()).DateTime : (DateTime?)null,\r\n                lastAccess = session.TryGetProperty(&quot;lastAccess&quot;, out var la) ? DateTimeOffset.FromUnixTimeMilliseconds(la.GetInt64()).DateTime : (DateTime?)null,\r\n                clients = session.TryGetProperty(&quot;clients&quot;, out var cl) ? cl.EnumerateObject().ToDictionary(c =&gt; c.Name, c =&gt; c.Value.GetString()) : null\r\n            }).ToList()\r\n        });\r\n    }\r\n\r\n    if (response.StatusCode == System.Net.HttpStatusCode.NotFound)\r\n        return Results.NotFound(new { error = &quot;Kullan\u0131c\u0131 bulunamad\u0131!&quot; });\r\n\r\n    var errorContent = await response.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<h5><span class=\"ez-toc-section\" id=\"Access_Tokeni_Cozumleyelim\"><\/span>Access Token&#8217;\u0131 \u00c7\u00f6z\u00fcmleyelim<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u015eimdi ise Keycloak \u00fczerinden hangi grant type ile \u00fcretilmi\u015f olursa olsun, bir access token&#8217;\u0131 \u00e7\u00f6z\u00fcmleyerek i\u00e7eri\u011finde yer alan claim&#8217;leri birlikte inceleyelim. Tabi bunun i\u00e7in <a href=\"https:\/\/www.jwt.io\/\" target=\"_blank\">jwt.io<\/a>&#8216;dan istifade edece\u011fimizi s\u00f6ylemeye gerek yok san\u0131r\u0131m \ud83d\ude42<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-6.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"880\" height=\"822\" class=\"aligncenter size-full wp-image-28351\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-6.png 880w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-6-300x280.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-6-768x717.png 768w\" sizes=\"auto, (max-width: 880px) 100vw, 880px\" \/><\/a>Burada claim&#8217;lere dikkat ederseniz e\u011fer baz\u0131 rollerin default olarak geldi\u011fini g\u00f6receksiniz.<\/p>\n<p>Evet, bizler bu \u00f6rne\u011fimizde <code>gncy<\/code> username&#8217;ine sahip olan kullan\u0131c\u0131ya herhangi bir rol tan\u0131mlamaks\u0131z\u0131n token talebinde bulunmu\u015ftuk. Ama bak\u0131yoruz ki, hem realm seviyesinde hem de client seviyesinde default olarak tan\u0131ml\u0131 gelen rolleri g\u00f6zlemlemekteyiz.<\/p>\n<p><strong>Peki bu yetkiler nereden gelmektedir?<\/strong><br \/>\nBu roller Keycloak&#8217;un tasar\u0131m\u0131 gere\u011fi otomatik olarak gelmektedir. \u015e\u00f6yle ki;<\/p>\n<ul style=\"font-size:15px;\">\n<li><code>offline_access<\/code> ve <code>uma_authorization<\/code> rolleri realm seviyesinden default olarak gelmektedir.<\/li>\n<li><code>manage-account<\/code>, <code>view-profile<\/code> ve <code>manage-account-links<\/code> rolleri ise client seviyesinden default olarak gelmektedir.<\/li>\n<\/ul>\n<p><strong>Peki neden bunlar default gelmektedir?<\/strong><br \/>\nBu yetkiler realm settings k\u0131sm\u0131nda varsay\u0131lan olarak ayarland\u0131\u011f\u0131 i\u00e7in&#8230;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"1640\" height=\"658\" class=\"aligncenter size-full wp-image-28352\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7.png 1640w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7-300x120.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7-1024x411.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7-768x308.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-7-1536x616.png 1536w\" sizes=\"auto, (max-width: 1640px) 100vw, 1640px\" \/><\/a><em>Ee iyi de hoca, bu g\u00f6rselde <code>default-roles-master<\/code> ve <code>manage-account-links<\/code> yetkileri yok!<\/em> dedi\u011finizi duyar gibiyim&#8230; Evet, bunlardan <code>manage-account-links<\/code> yetkisi <code>manage-account<\/code>&#8216;la birle\u015ftirilmi\u015f oldu\u011fu i\u00e7in, dolay\u0131s\u0131yla <code>manage-account<\/code> eklendi\u011finde otomatik token&#8217;a eklenmekte, <code>default-roles-master<\/code> ise kullan\u0131c\u0131ya default olarak eklenen tek rol oldu\u011fu i\u00e7in o da haliyle token&#8217;da g\u00f6z\u00fckmektedir. Bunlar\u0131n g\u00f6rsellerini payla\u015fmasam da sizler gidip kendiniz g\u00f6zlemleyebilirsiniz \ud83d\ude42<\/p>\n<h5><span class=\"ez-toc-section\" id=\"UserInfo_Endpoint_ile_Kullanici_Bilgilerine_Erisim\"><\/span>UserInfo Endpoint ile Kullan\u0131c\u0131 Bilgilerine Eri\u015fim<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>UserInfo, access token \u00fczerinden kullan\u0131c\u0131ya ait bilgileri (claims) okumak i\u00e7in kullan\u0131lan standart bir OpenID Connect endpoint&#8217;idir. \u00d6zellikle password grant, authorization code ve refresh token ak\u0131\u015flar\u0131nda elde edilen token&#8217;lardan sonra s\u0131k\u00e7a kullan\u0131lmaktad\u0131r. <\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-8.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4-8.png\" alt=\"Keycloak&#039;da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"178\" height=\"105\" class=\"alignleft size-full wp-image-28355\" \/><\/a>UserInfo endpoint&#8217;i ile ilgili token&#8217;\u0131n kime ait oldu\u011fu bilgisini rahatl\u0131kla edinebilmekteyiz. \u015e\u00f6yle ki; bir \u00f6nceki ba\u015fl\u0131kta access token&#8217;\u0131 \u00e7\u00f6z\u00fcmlemi\u015f ve claim&#8217;lerini incelemi\u015ftik. Hatta dikkat ettiyseniz, \u00e7\u00f6z\u00fcmlenmi\u015f token g\u00f6rselinde bu token&#8217;\u0131n kime ait oldu\u011funa dair \u00f6zel bilgilerin oldu\u011fu yandaki b\u00f6l\u00fcm mevcuttur. \u0130\u015fte bizler, eldeki token&#8217;da bulunan bu kullan\u0131c\u0131 bilgilerine, token&#8217;\u0131 decode etmeye gerek kalmaks\u0131z\u0131n UserInfo endpoint&#8217;inden istifade ederek h\u0131zl\u0131ca eri\u015febilmekteyiz.<\/p>\n<div style=\"background: #0f172a;color: #38bdf8;padding: 16px 20px;border-radius: 12px;font-family: system-ui, -apple-system, sans-serif;border: 1px solid #334155;margin: 1.2em 0;box-shadow: 0 4px 15px rgba(0,0,0,0.25);text-decoration: none;font-weight: 500;word-break: break-all;transition: color 0.2s;\">\n    <strong style=\"color:#60a5fa;font-size:15px;\">\ud83d\udd17 GET \/realms\/{realm}\/protocol\/openid-connect\/userinfo<br \/>\n<\/strong>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/user\/userinfo\/{realm}&quot;, async (string realm, IHttpClientFactory httpClientFactory, &#x5B;Microsoft.AspNetCore.Mvc.FromHeader(Name = &quot;Authorization&quot;)] string? authorization) =&gt;\r\n{\r\n    using var httpClient = httpClientFactory.CreateClient(&quot;keycloak&quot;);\r\n\r\n    if (string.IsNullOrEmpty(authorization) || !authorization.StartsWith(&quot;Bearer &quot;, StringComparison.OrdinalIgnoreCase))\r\n        return Results.Unauthorized();\r\n\r\n    var accessToken = authorization.Substring(&quot;Bearer &quot;.Length).Trim();\r\n\r\n    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, accessToken);\r\n\r\n    var response = await httpClient.GetAsync($&quot;\/realms\/{realm}\/protocol\/openid-connect\/userinfo&quot;);\r\n\r\n    if (response.IsSuccessStatusCode)\r\n    {\r\n        var userInfoContent = await response.Content.ReadAsStringAsync();\r\n        var userInfo = JsonSerializer.Deserialize&lt;JsonElement&gt;(userInfoContent);\r\n\r\n        return Results.Ok(userInfo);\r\n    }\r\n\r\n    if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)\r\n        return Results.Unauthorized();\r\n\r\n    var errorContent = await response.Content.ReadAsStringAsync();\r\n    return Results.BadRequest(new { error = errorContent });\r\n});\r\n<\/pre>\n<\/div>\n<p><div id=\"attachment_28358\" style=\"width: 417px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-28358\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png.png\" alt=\"Keycloak\u2019da Derinlemesine Kullan\u0131c\u0131 \u0130\u015flemleri #4\" width=\"407\" height=\"197\" class=\"size-full wp-image-28358\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png.png 407w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/01\/Keycloakda-Derinlemesine-Kullanici-Islemleri-4.png-300x145.png 300w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><\/a><p id=\"caption-attachment-28358\" class=\"wp-caption-text\">UserInfo neticesi&#8230;<\/p><\/div>Misal olarak yukar\u0131daki \u00f6rnek \u00e7al\u0131\u015fmaya g\u00f6z atarsan\u0131z e\u011fer request&#8217;in <em>Authorization<\/em> header key&#8217;inden token de\u011feri al\u0131nmakta ve ilgili endpoint&#8217;e <em>GET<\/em> iste\u011fi e\u015fli\u011finde g\u00f6nderilmektedir. Tabi bu iste\u011fin ba\u015far\u0131yla d\u00f6n\u00fc\u015f yapabilmesi i\u00e7in ilgili token talep edilirken <code>openid<\/code> scope&#8217;u e\u015fli\u011finde edilmesi zaruridir. Aksi taktirde 403 status code&#8217;u e\u015fli\u011finde yetkisiz bir i\u015flem yap\u0131ld\u0131\u011f\u0131na dair neticeyle kar\u015f\u0131la\u015f\u0131l\u0131yor olunacakt\u0131r.<\/p>\n<p>Bu endpoint, \u00f6zellikle frontend taraf\u0131nda kullan\u0131c\u0131 profil bilgilerine ihtiya\u00e7 oldu\u011funda olduk\u00e7a kullan\u0131\u015fl\u0131 olmaktad\u0131r. Ayr\u0131ca API Gateway&#8217;in de yer yer kullan\u0131c\u0131 bilgisi istemesinde de bu endpoint&#8217;ten istifade edilmektedir.<\/p>\n<p>Nihai olarak;<br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Keycloak, yaln\u0131zca bir kimlik do\u011frulama arac\u0131 de\u011fil, do\u011fru kullan\u0131ld\u0131\u011f\u0131nda son derece esnek ve g\u00fc\u00e7l\u00fc bir kullan\u0131c\u0131 y\u00f6netim platformu sunan bir teknolojidir. Bu yaz\u0131da, Keycloak \u00fczerinde \u00e7o\u011fu zaman y\u00fczeysel ge\u00e7ilen ancak ger\u00e7ek hayatta s\u0131k\u00e7a ihtiya\u00e7 duyulan kullan\u0131c\u0131 y\u00f6netimi senaryolar\u0131n\u0131 derinlemesine ele alm\u0131\u015f ve kullan\u0131c\u0131 attribute&#8217;lar\u0131n\u0131n hem aray\u00fcz hem de Administration REST API \u00fczerinden nas\u0131l y\u00f6netilece\u011fini, ge\u00e7ici ve kal\u0131c\u0131 \u015fifre tan\u0131mlama s\u00fcre\u00e7lerini, Password Grant Type ile kullan\u0131c\u0131 do\u011frulaman\u0131n kritik noktalar\u0131n\u0131 ve aktif oturum bilgilerinin nas\u0131l elde edilebilece\u011fini ad\u0131m ad\u0131m incelemi\u015f bulunuyor ve b\u00f6ylece kurumsal \u00f6l\u00e7ekte g\u00fcvenli ve s\u00fcrd\u00fcr\u00fclebilir bir kimlik altyap\u0131s\u0131 kurman\u0131n temel ta\u015flar\u0131n\u0131 pratik dokunu\u015flarla tecr\u00fcbe etmi\u015f oluyoruz.<\/p>\n<p>Ayr\u0131ca \u00fcretilen token&#8217;lar\u0131n i\u00e7eri\u011fini \u00e7\u00f6z\u00fcmleyerek hangi rollerin ve claim&#8217;lerin neden varsay\u0131lan olarak geldi\u011fini netle\u015ftirmi\u015f, UserInfo endpoint&#8217;i \u00fczerinden kullan\u0131c\u0131 bilgilerine nas\u0131l eri\u015filebilece\u011fini de uygulamal\u0131 olarak g\u00f6stermi\u015f bulunuyoruz.<\/p>\n<p>Bir sonraki i\u00e7eri\u011fimizde bu yap\u0131lar\u0131n authorization, role ve scope tasar\u0131m\u0131n\u0131 ve daha ileri g\u00fcvenlik senaryolarda nas\u0131l konumland\u0131r\u0131labileceklerini ele al\u0131yor olaca\u011f\u0131z.<\/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 \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki GitHub adresiden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/Keycloak.Examples\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/Keycloak.Examples<\/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, Bu i\u00e7eri\u011fimizde; Keycloak platformunda kullan\u0131c\u0131 y\u00f6netimiyle ilgili s\u0131k kar\u015f\u0131la\u015f\u0131lan ancak genellikle y\u00fczeysel ge\u00e7ilen baz\u0131 ek senaryolara odaklan\u0131yor olaca\u011f\u0131z. Bu senaryolar; Keycloak&#8217;\u0131n varsay\u0131lan olarak sundu\u011fu kullan\u0131c\u0131 bilgilerine nas\u0131l ek alanlar eklenebilece\u011fi, kullan\u0131c\u0131lara ge\u00e7ici veya&#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":[313,5612,5555,5603,5604,5609,5607,5608,5611,5610,5606,5605,5613,3894],"class_list":["post-28334","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-keycloak","tag-attribute","tag-direct-access-grants","tag-keycloak","tag-keycloak-attribute","tag-keycloak-user","tag-password-grant-type","tag-permanent","tag-permanent-password","tag-resource-owner-grant","tag-resource-owner-password-credentials-grant","tag-temporary","tag-temporary-password","tag-userinfo","tag-userinfo-endpoint"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28334","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=28334"}],"version-history":[{"count":16,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28334\/revisions"}],"predecessor-version":[{"id":28362,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28334\/revisions\/28362"}],"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=28334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=28334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=28334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}