﻿
{"id":28592,"date":"2026-04-26T19:12:29","date_gmt":"2026-04-26T19:12:29","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=28592"},"modified":"2026-04-26T19:12:29","modified_gmt":"2026-04-26T19:12:29","slug":"keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/","title":{"rendered":"Keycloak&#8217;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim&#8230; #12"},"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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Advanced_Authorization_Services_Nedir\" >Advanced Authorization Services 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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Klasik_Yetkilendirme_Yaklasimindan_Farki_Nedir\" >Klasik Yetkilendirme Yakla\u015f\u0131m\u0131ndan Fark\u0131 Nedir?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Sistemin_4_Temel_Parcasi\" >Sistemin 4 Temel Par\u00e7as\u0131<\/a><\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#UMA_20_Nedir_Ne_Getirmektedir\" >UMA 2.0 Nedir? Ne Getirmektedir?<\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Nasil_Calismaktadir\" >Nas\u0131l \u00c7al\u0131\u015fmaktad\u0131r?<\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#UMA_20i_Kullanirken_Nelere_Dikkat_Etmek_Gerekmektedir\" >UMA 2.0&#8217;\u0131 Kullan\u0131rken Nelere Dikkat Etmek Gerekmektedir?<\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#13_Kritik_Soru_13_Kritik_Cevap\" >13 Kritik Soru \/ 13 Kritik Cevap<\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Keycloak_AspNET_Core_%E2%86%92_Policy-Based_Authorization\" >Keycloak + Asp.NET Core \u2192 Policy-Based Authorization<\/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\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Keycloak_AspNET_Core_%E2%86%92_Resource-Based_Authorization_RBA\" >Keycloak + Asp.NET Core \u2192 Resource-Based Authorization (RBA)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#Keycloak_AspNET_Core_%E2%86%92_UMA_20\" >Keycloak + Asp.NET Core \u2192 UMA 2.0<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloakda-advanced-authorization-services-uma-2-0-sistemini-inceleyelim-12\/#UMAyi_Custom_Authorization_Requirement_Handler_Yoluyla_Uygulama_En_Dogru_Yol\" >UMA&#8217;y\u0131 Custom Authorization Requirement + Handler Yoluyla Uygulama (En Do\u011fru Yol)<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<\/p>\n<p>Bu i\u00e7eri\u011fimizde, <em>UMA 2.0<\/em> standard\u0131n\u0131 temel alan; klasik <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/role-based-authorization\/\" target=\"_blank\">rol bazl\u0131 yetkilendirme<\/a> mant\u0131\u011f\u0131ndan \u00e7ok daha g\u00fc\u00e7l\u00fc bir yap\u0131 sunan policy (kural) tabanl\u0131 eri\u015fim kontrol sistemi olan <em>Advanced Authorization Services<\/em> sistemini teorik olarak ele alacak ve edinece\u011fimiz fark\u0131ndal\u0131k \u00fczerine Asp.NET Core&#8217;da pratiksel deneyimlerde bulunaca\u011f\u0131z. O halde, konunun temellerini ad\u0131m ad\u0131m inceleyerek ba\u015flayal\u0131m&#8230;<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Advanced_Authorization_Services_Nedir\"><\/span>Advanced Authorization Services Nedir?<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Keycloak Advanced Authorization Services, uygulamalarda eri\u015fim kontrol\u00fcn\u00fc basit rol kontrol\u00fcnden \u00e7\u0131kar\u0131p dinamik, kural tabanl\u0131 ve ba\u011flama duyarl\u0131 hale getiren geli\u015fmi\u015f bir yetkilendirme sistemidir.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Klasik_Yetkilendirme_Yaklasimindan_Farki_Nedir\"><\/span>Klasik Yetkilendirme Yakla\u015f\u0131m\u0131ndan Fark\u0131 Nedir?<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Klasik yetkilendirme yakla\u015f\u0131m\u0131nda kullan\u0131c\u0131 sisteme giri\u015f yapt\u0131ktan sonra yaln\u0131zca token i\u00e7indeki rol\u00fcne bak\u0131larak karar verilir&#8230; Buna \u00f6rnek vermemiz gerekirse e\u011fer; <em>-kullan\u0131c\u0131 <code>admin<\/code> ise izin verilsin, <code>user<\/code> ise verilmesin-<\/em> gibi basit kurallar uygulan\u0131r. Ancak bu y\u00f6ntem eri\u015filen verinin ne oldu\u011fu, kime ait oldu\u011fu ya da hangi ko\u015fullarda eri\u015fildi\u011fi gibi kritik detaylar\u0131 dikkate almad\u0131\u011f\u0131 i\u00e7in ger\u00e7ek d\u00fcnya senaryolar\u0131nda yetersiz kalabilmektedir.<\/p>\n<p>Buna kar\u015f\u0131l\u0131k Keycloak Advanced Authorization Services, UMA 2.0 temelli yap\u0131s\u0131yla yetkilendirmeyi sadece role ba\u011fl\u0131 olmaktan \u00e7\u0131kar\u0131p, kullan\u0131c\u0131n\u0131n kim oldu\u011fu, hangi kayna\u011fa eri\u015fmek istedi\u011fi, bu kayna\u011f\u0131n kime ait oldu\u011fu ve eri\u015fimin hangi \u015fartlarda ger\u00e7ekle\u015fti\u011fi gibi dinamik fakt\u00f6rleri de\u011ferlendiren policy (kural) tabanl\u0131 bir sisteme d\u00f6n\u00fc\u015ft\u00fcrerek \u00e7ok daha esnek ve g\u00fc\u00e7l\u00fc bir kontrol mekanizmas\u0131 sa\u011flamaktad\u0131r.<\/p>\n<blockquote style=\"font-size:12px;\"><p><em>Advanced Authorization; <em>-kim, hangi kayna\u011fa, hangi \u015fartlarda eri\u015febilir?-<\/em> sorununa policy (kural) ile \u00e7\u00f6z\u00fcm getirmektedir.<\/em><\/p><\/blockquote>\n<h4><span class=\"ez-toc-section\" id=\"Sistemin_4_Temel_Parcasi\"><\/span>Sistemin 4 Temel Par\u00e7as\u0131<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Keycloak&#8217;un Advanced Authorization yap\u0131s\u0131nda yetkilendirme; korunan varl\u0131klar\u0131 temsil eden <em style=\"color:purple;\">resource<\/em>, bu varl\u0131klar \u00fczerinde yap\u0131labilecek i\u015flemleri belirleyen <em style=\"color:purple;\">scope<\/em>, eri\u015fim karar\u0131n\u0131 veren kurallar\u0131 i\u00e7eren <em style=\"color:purple;\">policy<\/em> ve t\u00fcm bunlar\u0131n birle\u015fimiyle <em>-kim, hangi kayna\u011fa, hangi \u015fartlarda eri\u015febilir?-<\/em> sorusuna cevap veren <em style=\"color:purple;\">permission<\/em> bile\u015fenlerinden olu\u015fmaktad\u0131r.<\/p>\n<table style=\"border-collapse:collapse;font-family:Arial,sans-serif;font-size:12px;width:100%;\">\n<tr style=\"background:#f2f2f2;\">\n<th style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Par\u00e7a<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;text-align:left;\">A\u00e7\u0131klama<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;text-align:left;\">\u00d6rnek<\/th>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Resource<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:justify;\">Korunan varl\u0131kt\u0131r. Yani sistemde eri\u015fimini kontrol etmek istedi\u011fimiz somut &#8220;\u015fey&#8221;dir. Kullan\u0131c\u0131lar\u0131n g\u00f6rmesini, de\u011fi\u015ftirmesini ya da silmesini s\u0131n\u0131rland\u0131rmak istedi\u011fimiz veri veya varl\u0131kt\u0131r. \u00d6rne\u011fin bir sipari\u015f kayd\u0131, bir dosya ya da bir ayar objesi gibi d\u00fc\u015f\u00fcn\u00fclebilir. Ve Keycloak bu &#8220;\u015fey&#8221; \u00fczerine kimin ne yapabilece\u011fini belirlemek i\u00e7in onu bir resource olarak tan\u0131mlamaktad\u0131r.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;\">\/orders\/123<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Scope<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:justify;\">Bir kullan\u0131c\u0131n\u0131n tan\u0131mlanan resource \u00fczerinde tam olarak ne yapabilece\u011fini ifade eden yetki tipidir. Yani mesele sadece <em>-eri\u015febilir mi?-<\/em> de\u011fil, <em>-eri\u015fince ne yapabilir?-<\/em> sorusudur! Bu da <em>read<\/em>, <em>write<\/em>, <em>delete<\/em> ve <em>approve<\/em> gibi aksiyonlarla belirlenmektedir. B\u00f6ylece ayn\u0131 kayna\u011fa farkl\u0131 kullan\u0131c\u0131lar farkl\u0131 seviyelerde yetkiyle eri\u015febilir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;\">read, write<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Policy<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:justify;\">Bir kullan\u0131c\u0131n\u0131n belirli bir resource \u00fczerinde tan\u0131mlanan scope&#8217;u kullan\u0131p kullanamayaca\u011f\u0131n\u0131 belirleyen karar\/kural mekanizmas\u0131d\u0131r. Sistemin as\u0131l &#8220;akl\u0131&#8221; burada \u00e7al\u0131\u015fmaktad\u0131r ve kullan\u0131c\u0131 rol\u00fc, kayna\u011f\u0131n sahibi olup olmad\u0131\u011f\u0131, kullan\u0131c\u0131ya ait \u00f6zellikler ve zaman gibi fakt\u00f6rlere bakarak eri\u015fime izin verir ya da reddeder. Hatta istenirse \u00f6zel kod yaz\u0131larak bu karar tamamen ihtiyaca g\u00f6re \u015fekillendirilebilir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;\">admin ise izin ver<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Permission<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:justify;\">Resource, scope ve policy&#8217;nin bir araya gelerek olu\u015fturdu\u011fu nihai karar yap\u0131s\u0131d\u0131r. Sistemin <em>-bu kullan\u0131c\u0131, \u015fu kayna\u011fa, \u015fu i\u015flemi yapabilir mi?-<\/em> sorusuna verdi\u011fi kesin cevapt\u0131r ve esas\u0131nda tek ba\u015f\u0131na bir \u015fey de\u011fildir! Bu \u00fc\u00e7 bile\u015fenin birle\u015fimiyle olu\u015fan ve eri\u015fime izin verilip verilmeyece\u011fini belirleyen nihai noktad\u0131r.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;\">admin \u2192 \/orders read<\/td>\n<\/tr>\n<\/table>\n<h4><span class=\"ez-toc-section\" id=\"UMA_20_Nedir_Ne_Getirmektedir\"><\/span>UMA 2.0 Nedir? Ne Getirmektedir?<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>UMA 2.0 (User-Managed Access 2.0), klasik rol tabanl\u0131 yetkilendirmeden \u00e7ok daha esnek ve kullan\u0131c\u0131 odakl\u0131 bir eri\u015fim kontrol standard\u0131d\u0131r. Temel fikir olarak; kaynak (resource) sahiplerinin, kendi kaynaklar\u0131na kimin hangi ko\u015fullarda eri\u015febilece\u011fini merkezi bir sistem \u00fczerinden y\u00f6netebilmesidir. B\u00f6ylece art\u0131k yetkiyi sadece <em>admin<\/em>, <em>user<\/em> gibi statik rollere de\u011fil, dinamik kurallara ve ko\u015fullara ba\u011fl\u0131 olarak vermeyi sa\u011flamaktad\u0131r.<\/p>\n<p>UMA 2.0 ile gelen temel yenilikler \u015funlard\u0131r:<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong><em>Kullan\u0131c\u0131 Kontrol\u00fc<\/em><\/strong><br \/>\nKaynak sahibi, kendi verisine kimlerin eri\u015febilece\u011fini y\u00f6netebilir.\n<\/li>\n<li><strong><em>Ko\u015ful Tabanl\u0131 Eri\u015fim<\/em><\/strong><br \/>\nSaat, IP, cihaz, kullan\u0131c\u0131 ge\u00e7mi\u015fi vs. gibi parametreler izin karar\u0131na dahil edilebilir.\n<\/li>\n<li><strong><em>Merkezi Yetkilendirme<\/em><\/strong><br \/>\nAPI veya uygulama client&#8217;lar\u0131, merkezi bir izin sunucusuna (Keycloak gibi) eri\u015fim izni sorarak davran\u0131\u015flar\u0131n\u0131 \u015fekillendirebilir.\n<\/li>\n<li><strong><em>Dinamik Token (RPT \u2013 Requesting Party Token)<\/em><\/strong><br \/>\nEri\u015fim iste\u011fi s\u0131ras\u0131nda politika ve kurallar de\u011ferlendirilir, sonucu belirten \u00f6zel token olu\u015fturulur.\n<\/li>\n<li><strong><em>\u00c7oklu Sistem Entegrasyonu<\/em><\/strong><br \/>\nKullan\u0131c\u0131 yahut kaynak bilgisi farkl\u0131 sistemlerde gelebilir. UMA bu tarz heterojen ortamlara da uyum sa\u011flayabilir.\n<\/li>\n<\/ul>\n<p>K\u0131saca UMA 2.0; <em>-kim, neye, ne zaman, hangi ko\u015fullarda eri\u015febilir?-<\/em> sorular\u0131n\u0131 dinamik ve merkezi olarak y\u00f6netebilmemizi sa\u011flayan ve \u00f6zellikle \u00e7ok kullan\u0131c\u0131l\u0131, \u00e7ok sistemli ve hassas veri ortamlar\u0131nda kritik bir esneklik ve g\u00fcvenlik sa\u011flayan bir standartt\u0131r.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Nasil_Calismaktadir\"><\/span>Nas\u0131l \u00c7al\u0131\u015fmaktad\u0131r?<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"1536\" height=\"1024\" class=\"aligncenter size-full wp-image-28597\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.png 1536w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-300x200.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1024x683.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-768x512.png 768w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><\/a>UMA 2.0&#8217;\u0131n ak\u0131\u015f mant\u0131\u011f\u0131 yukar\u0131daki g\u00f6rselde oldu\u011fu gibi cereyan etmektedir:<\/p>\n<ol style=\"font-size:14px;\">\n<li><em>\u0130stek<\/em>: Client, API&#8217;ye istek atar.<\/li>\n<li><em>Soru<\/em>: API, Keycloak&#8217;a <em>-bu kullan\u0131c\u0131 bu resource&#8217;a eri\u015febilir mi?-<\/em> diye sorar.<\/li>\n<li><em>Policy Kontrol<\/em>: Keycloak, policy&#8217;leri \u00e7al\u0131\u015ft\u0131r\u0131r ve karar \u00fcretir.<\/li>\n<li><em>Sonu\u00e7<\/em>: Nihai olarak eri\u015fimi izin verilir yahut engellenir.<\/li>\n<\/ol>\n<p>Tabi bu \u015fema client bazl\u0131 mant\u0131\u011f\u0131 yans\u0131tmaktad\u0131r. Bir yandan kullan\u0131c\u0131 bazl\u0131 mant\u0131\u011f\u0131 da ele al\u0131rsak;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"1536\" height=\"1024\" class=\"aligncenter size-full wp-image-28598\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1.png 1536w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1-300x200.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1-1024x683.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-1-768x512.png 768w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><\/a>\u015feklinde bir ak\u0131\u015f d\u00fc\u015f\u00fcnebiliriz. Burada s\u00fcreci g\u00f6zlemlersek;<\/p>\n<ol style=\"font-size:14px;\">\n<li>Kullan\u0131c\u0131 login olup, access token al\u0131r.<\/li>\n<li>Ard\u0131ndan API&#8217;ye gidip <em>-ben bu resource&#8217;a eri\u015fmek istiyorum-<\/em> der.<\/li>\n<li>Keycloak gerekli kontrolleri sa\u011flar ve izin var m\u0131 yok mu de\u011ferlendirir. E\u011fer izin yoksa permission ticket \u00fcretir, varsa da ticket&#8217;a gerek kalmaks\u0131z\u0131n RPT \u00fcretilir.\n<div style=\"background-color:#f5f7fa; border-left:4px solid #4a90e2; padding:10px 12px; margin:10px 0; font-style:italic; color:#333;\">\n<em><strong>Permission Ticket Nedir?<\/strong><\/em><br \/>\nBu ticket, <em>-bu kullan\u0131c\u0131 \u015fu resource&#8217;a eri\u015fmek istiyor-<\/em> bilgisini ta\u015f\u0131yan ge\u00e7ici bir izin talebi belgesidir. Keycloak, bu ticket ile client tekrar geldi\u011fi taktirde izin s\u00fcrecini ba\u015flatmaktad\u0131r.<\/p>\n<p>Burada <em>-izin yoksa direkt reddet ge\u00e7-<\/em> mant\u0131\u011f\u0131nda bir davran\u0131\u015f bekleyebilirsiniz. Ancak UMA 2.0&#8217;\u0131n amac\u0131 klasik sistemlerden farkl\u0131 olarak reddetmek odakl\u0131 de\u011fil, izin s\u00fcrecini y\u00f6netmek odakl\u0131d\u0131r. Klasik sistemlerde izin yoksa e\u011fer 403 status code&#8217;uyla s\u00fcre\u00e7 sonland\u0131r\u0131l\u0131r. Ancak UMA 2.0&#8217;da izin olmasa dahi belki al\u0131nabilece\u011fi d\u00fc\u015f\u00fcn\u00fcld\u00fc\u011f\u00fc i\u00e7in s\u00fcre\u00e7 ba\u015flat\u0131l\u0131r. <em><strong>Nas\u0131l belki al\u0131nabilir hoca la&#8230;<\/strong><\/em> diye sorarsan\u0131z, d\u00fc\u015f\u00fcn\u00fcn&#8230; Kaynak sahibi belki izin verecektir, belki de eri\u015fimi admin onaylayacakt\u0131r ya da sistem ko\u015fullara g\u00f6re izni sa\u011flayacakt\u0131r. Haliyle bu \u015fekilde opsiyonel olan bir s\u00fcreci de\u011ferlendirmek, evet, ad\u0131 \u00fczerinden bir s\u00fcre\u00e7 ba\u015flatmay\u0131 gerektirmektedir. Bunu da yukar\u0131da s\u00f6ylendi\u011fi gibi permission ticket ile ger\u00e7ekle\u015ftirmekteyiz.<\/p>\n<p>Tabi permission ticket davran\u0131\u015f\u0131;<\/p>\n<ul>\n<li>kullan\u0131c\u0131lar aras\u0131 veri payla\u015f\u0131m\u0131 s\u00fcre\u00e7lerinde,<\/li>\n<li>dosya \/ belge sistemlerinde,<\/li>\n<li>sosyal platformlarda,<\/li>\n<li>AI agent&#8217;lar\u0131n kullan\u0131c\u0131lar ad\u0131na i\u015flem yapt\u0131\u011f\u0131 s\u00fcre\u00e7lerde,<\/li>\n<li>ve dinamik izin ak\u0131\u015flar\u0131nda<\/li>\n<\/ul>\n<p>olduk\u00e7a mant\u0131kl\u0131d\u0131r.<\/p>\n<p>Bunlar\u0131n d\u0131\u015f\u0131nda tabi ki de basit CRUD API&#8217;lerinde yahut sadece admin veya user gibi basit ayr\u0131mlar\u0131n ve statik rollerin oldu\u011fu sistemlerde kullan\u0131m\u0131 olduk\u00e7a gereksizdir!\n<\/p><\/div>\n<\/li>\n<li>Client, \u00fcretilen permission ticket ile tekrar Keycloak&#8217;a gider.<\/li>\n<li>Keycloak, policy&#8217;leri \u00e7al\u0131\u015ft\u0131r\u0131r ve uygunsa RPT \u00fcretir.\n<div style=\"background-color:#f5f7fa; border-left:4px solid #4a90e2; padding:10px 12px; margin:10px 0; font-style:italic; color:#333;\">\n<em><strong>RPT (Requesting Party Token) Nedir?<\/strong><\/em><br \/>\nRPT, UMA 2.0 kapsam\u0131nda \u00fcretilen, kullan\u0131c\u0131n\u0131n belirli bir resource&#8217;a hangi izinlerle eri\u015febilece\u011fini g\u00f6steren \u00f6zel bir access token&#8217;d\u0131r. Yani <em>-bu kullan\u0131c\u0131 \u015funlar\u0131 yapabilir-<\/em> bilgisini ta\u015f\u0131yan token&#8217;d\u0131r. Ama dikkat edin ki bir access token de\u011fildir! Access token ile RPT evet&#8230; birbirlerine benzemektedirler, ikisi de JWT&#8217;dir, evet&#8230; ikisi de Keycloak taraf\u0131ndan \u00fcretilir, evet&#8230; her ikisi de request s\u00fcre\u00e7lerinde authorization header&#8217;\u0131 \u00fczerinden API&#8217;lere g\u00f6nderilir&#8230; Ancak bilinmelidir ki farkl\u0131d\u0131rlar \ud83d\ude42 Access token&#8217;\u0131n amac\u0131 kimlikken (authentication), RPT&#8217;nin yetkidir (authorization). Access token, <em>-ben kimim-<\/em> sorusuna cevap verirken, RPT ise <em>-ne yapabilirim-<\/em> sorusuna cevap vermektedir. Haliyle bir \u00e7al\u0131\u015fmada access token olmaks\u0131z\u0131n RPT al\u0131nmas\u0131 m\u00fcmk\u00fcn de\u011fildir!\n<\/div>\n<\/li>\n<\/ol>\n<h4><span class=\"ez-toc-section\" id=\"UMA_20i_Kullanirken_Nelere_Dikkat_Etmek_Gerekmektedir\"><\/span>UMA 2.0&#8217;\u0131 Kullan\u0131rken Nelere Dikkat Etmek Gerekmektedir?<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>UMA 2.0 do\u011fru kullan\u0131lmad\u0131\u011f\u0131 taktirde a\u015f\u0131r\u0131 karma\u015f\u0131k bir canavara d\u00f6n\u00fc\u015febilir. Bu nedenle konuya ili\u015fkin pratik ve net uyar\u0131larla dikkat edilmesi gereken hususlara dair fark\u0131ndal\u0131k olu\u015fturmak \u00f6nem arz etmektedir.<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong>UMA 2.0 kullan\u0131lacaksa ger\u00e7ekten gerekli mi sorusu sorulmal\u0131d\u0131r!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken en kritik mesele, ger\u00e7ekten buna ihtiya\u00e7 olup olmad\u0131\u011f\u0131n\u0131 do\u011fru de\u011ferlendirmektir. \u00c7\u00fcnk\u00fc basit CRUD i\u015flemleri, klasik admin\/user ayr\u0131m\u0131 veya statik rol yap\u0131lar\u0131 olan bir sistemde UMA gereksiz karma\u015fa ve performans maliyeti getirecektir. Buna kar\u015f\u0131l\u0131k kullan\u0131c\u0131lar aras\u0131 veri payla\u015f\u0131m\u0131, dinamik izin talepleri ve onay s\u00fcre\u00e7leri, AI agent&#8217;lar\u0131n\u0131n kontroll\u00fc aksiyon almas\u0131 veya <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/multitenancy\/\" target=\"_blank\">multi-tenant<\/a> ve karma\u015f\u0131k eri\u015fim kurallar\u0131 gibi durumlarda ciddi bir esneklik ve g\u00fc\u00e7 sa\u011flayacakt\u0131r. Bu y\u00fczden yanl\u0131\u015f yerde kullan\u0131ld\u0131\u011f\u0131nda sistemi yava\u015flatan bir y\u00fcke d\u00f6n\u00fc\u015febilme ihtimali s\u00f6z konusudur.\n<\/li>\n<li><strong>Resource tasar\u0131m\u0131 do\u011fru yap\u0131lmal\u0131d\u0131r!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken <code>resource<\/code> tasar\u0131m\u0131n\u0131 do\u011fru yapmak kritik \u00f6neme sahiptir. \u00c7\u00fcnk\u00fc, her bir veri kayd\u0131n\u0131 ayr\u0131 bir resource olarak tan\u0131mlamak sistemde kontrol edilmesi gereken nesne say\u0131s\u0131n\u0131 a\u015f\u0131r\u0131 art\u0131raca\u011f\u0131 i\u00e7in ciddi performans problemlerine yol a\u00e7abilir. Bunun yerine benzer varl\u0131klar\u0131 mant\u0131kl\u0131 seviyede gruplayarak daha kaba (coarse-grained) bir yap\u0131 kurmak hem  y\u00f6netilebilirli\u011fi art\u0131r\u0131r hem de yetkilendirme s\u00fcre\u00e7lerinin daha h\u0131zl\u0131 ve verimli \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.\n<\/li>\n<li><strong>Scope&#8217;lar minimal tutulmal\u0131d\u0131r!<\/strong><br \/>\nScope&#8217;lar\u0131 m\u00fcmk\u00fcn oldu\u011funca sade ve az say\u0131da tutmak gerekmektedir. Her aksiyonu ayr\u0131 ayr\u0131 tan\u0131mlamak sistemi gereksiz karma\u015f\u0131k hale getirecek ve y\u00f6netimi zorla\u015ft\u0131racakt\u0131r. Bunun yerine read, write, delete gibi temel aksiyonlarla ilerleyip detayl\u0131 ayr\u0131mlar\u0131 policy taraf\u0131nda \u00e7\u00f6zmek hem daha esnek hem de daha s\u00fcrd\u00fcr\u00fclebilir bir yetkilendirme yap\u0131s\u0131 sa\u011flayacakt\u0131r.\n<\/li>\n<li><strong>Policy&#8217;ler sade ve deterministik olmal\u0131d\u0131r!<\/strong><br \/>\nKeycloak \u00fczerinde UMA 2.0 kullan\u0131rken policy&#8217;leri m\u00fcmk\u00fcn oldu\u011funca sade, k\u00fc\u00e7\u00fck ve deterministik tutmak gerekmektedir. \u00c7\u00fcnk\u00fc t\u00fcm mant\u0131\u011f\u0131 tek bir karma\u015f\u0131k policy i\u00e7inde toplamak, \u00f6zellikle JavaScript tabanl\u0131 kurallar\u0131n, d\u0131\u015f sistem \u00e7a\u011fr\u0131lar\u0131n\u0131n ve i\u00e7 i\u00e7e ge\u00e7mi\u015f \u015fartlar\u0131n oldu\u011fu senaryolar sistemi hem anla\u015f\u0131lmaz hem de zor debug edilebilir hale getirecektir. Bunun yerine her policy&#8217;nin tek bir i\u015fi yapt\u0131\u011f\u0131, m\u00fcmk\u00fcn oldu\u011funca token i\u00e7inde claim&#8217;lere dayanan ve birbirinden ba\u011f\u0131ms\u0131z \u00e7al\u0131\u015fan bir yap\u0131 kurmak hem performans art\u0131racak hem de yetkilendirme kararlar\u0131n\u0131n \u00f6ng\u00f6r\u00fclebilir ve y\u00f6netilebilir olmas\u0131n\u0131 sa\u011flayacakt\u0131r.\n<\/li>\n<li><strong>Token&#8217;\u0131n \u015fi\u015fmesine dikkat edilmelidir!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken RPT i\u00e7inde ta\u015f\u0131nan resource ve scope bilgilerinin gereksiz yere \u00e7o\u011falt\u0131lmas\u0131 token&#8217;\u0131n boyutunu b\u00fcy\u00fcterek hem a\u011f \u00fczerinden ta\u015f\u0131nan veri miktar\u0131n\u0131 art\u0131r\u0131r hem de her istekte do\u011frulama maliyetini y\u00fckselterek performans\u0131 olumsuz etkiler. Bu y\u00fczden m\u00fcmk\u00fcn oldu\u011funca daha genel (coarse-grained) resource tan\u0131mlar\u0131 yapmak ve sadece ger\u00e7ekten gerekli izinleri token&#8217;a dahil etmek sistemin daha h\u0131zl\u0131 ve verimli \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayacakt\u0131r.\n<\/li>\n<li><strong>Performans \u00f6nemsenmelidir! Hafife al\u0131nmamal\u0131d\u0131r!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken performans hafife al\u0131nmamal\u0131d\u0131r. \u00c7\u00fcnk\u00fc bu modelde klasik ak\u0131\u015fa ek olarak access token, permission ticket ve RPT \u00fcretimi gibi ekstra istek-cevap (roundtrip) s\u00fcre\u00e7leri s\u00f6z konusu olacakt\u0131r ve bunlar\u0131n her API \u00e7a\u011fr\u0131s\u0131nda tekrar etmesi sistemi ciddi \u015fekilde yava\u015flatacakt\u0131r. Bu y\u00fczden RPT&#8217;yi cache&#8217;lemek, her istekte tekrar Keycloak&#8217;a gitmemek ve backend taraf\u0131nda k\u0131sa s\u00fcreli \u00f6nbellekleme stratejileri kullanmak performans a\u00e7\u0131s\u0131ndan kritik bir optimizasyondur.\n<\/li>\n<li><strong>Stateless ve Stateful fark\u0131n\u0131 iyi anlamak gerekmektedir!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken klasik JWT yap\u0131s\u0131n\u0131n tamamen stateless olmas\u0131na kar\u015f\u0131l\u0131k UMA&#8217;n\u0131n permission ticket, policy evaluation ve RPT \u00fcretimi gibi s\u00fcre\u00e7lerle k\u0131smen stateful bir yap\u0131ya ge\u00e7ti\u011fini iyi anlamak gerekmektedir. \u00c7\u00fcnk\u00fc bu durum sistemin davran\u0131\u015f\u0131n\u0131 daha dinamik hale getirirken ayn\u0131 zamanda hata ay\u0131klamay\u0131 zorla\u015ft\u0131racak ve kararlar\u0131n sadece token i\u00e7eri\u011fine de\u011fil, anl\u0131k de\u011ferlendirme s\u00fcre\u00e7lerine de ba\u011fl\u0131 olmas\u0131na neden olacakt\u0131r.\n<\/li>\n<li><strong>Debugging plan\u0131n\u0131n haz\u0131r k\u0131ta olmas\u0131 faydal\u0131 olacakt\u0131r!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken en zor konulardan biri <em>-neden izin verilmedi?-<\/em> sorusuna cevap aramakt\u0131r&#8230; \u00c7\u00fcnk\u00fc kararlar sadece token&#8217;a bak\u0131larak de\u011fil, policy&#8217;lerin dinamik olarak \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131yla verilmektedir. Bu y\u00fczden Keycloak \u00fczerinde log&#8217;lar\u0131 aktif etmek, policy evaluation ara\u00e7lar\u0131n\u0131 kullanmak ve farkl\u0131 senaryolar\u0131 test edebilece\u011fin \u00f6rnek kullan\u0131c\u0131lar olu\u015fturmak, hatalar\u0131 h\u0131zl\u0131 te\u015fhis edebilmek ve sistemin nas\u0131l karar verdi\u011fini anlayabilmek a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir.\n<\/li>\n<li><strong>Client&#8217;a g\u00fcvenilmemeli, t\u00fcm yetkilendirme kontrolleri backend taraf\u0131ndan do\u011frulanmal\u0131d\u0131r!<\/strong><br \/>\nUMA 2.0 kullan\u0131rken en kritik g\u00fcvenlik noktalar\u0131ndan biri client&#8217;a asla g\u00fcvenilmemesi ve t\u00fcm yetkilendirme kontrollerinin backend taraf\u0131nda do\u011frulanmas\u0131 gereklili\u011fidir. \u00d6zellikle RPT i\u00e7indeki izinlerin ger\u00e7ekten ge\u00e7erli olup olmad\u0131\u011f\u0131n\u0131 sunucu taraf\u0131nda kontrol etmek ve yaln\u0131zca token&#8217;\u0131n varl\u0131\u011f\u0131na de\u011fil, i\u00e7indeki scope&#8217;lar\u0131n ilgili i\u015flem i\u00e7in uygun olup olmad\u0131\u011f\u0131na bakmak gerekmektedir! Aksi taktirde client manip\u00fclasyonlar\u0131 veya eksik kontroller ciddi g\u00fcvenlik a\u00e7\u0131klar\u0131na sebebiyet verebilir.\n<\/li>\n<\/ul>\n<h4><span class=\"ez-toc-section\" id=\"13_Kritik_Soru_13_Kritik_Cevap\"><\/span>13 Kritik Soru \/ 13 Kritik Cevap<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>\u015eimdi konuyu daha iyi anlayabilmek ve duvar k\u00f6\u015felerindeki k\u0131r\u0131nt\u0131lara kadar sindirebilmek i\u00e7in akla gelen gelmeyen t\u00fcm sorular\u0131 burada masaya yat\u0131r\u0131p cevapland\u0131rmaya \u00e7al\u0131\u015fal\u0131m:<\/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>Permission Explosion nedir?<\/em><\/strong><br \/>\nPermission Explosion (\u0130zin Patlamas\u0131), Keycloak gibi sistemlerde her kullan\u0131c\u0131, her resource ve her i\u015flem i\u00e7in ayr\u0131 ayr\u0131 izin tan\u0131mland\u0131\u011f\u0131nda ortaya \u00e7\u0131kan kontrols\u00fcz b\u00fcy\u00fcme problemidir. Bu durumda permission say\u0131s\u0131 katlanarak artar, sistem y\u00f6netilemez hale gelir, performans d\u00fc\u015fer ve token&#8217;lar \u015fi\u015fer. Bu y\u00fczden do\u011fru yakla\u015f\u0131m her ihtimal i\u00e7in ayr\u0131 izin \u00fcretmek yerine daha genel resource ve scope&#8217;lar tan\u0131mlay\u0131p eri\u015fim karar\u0131n\u0131 dinamik policy&#8217;lerle vermektir.\n<\/div>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 1 | <span style=\"color:#877572;\">UMA 2.0 ve normal access token aras\u0131ndaki fark nedir?<\/span><\/summary>\n<p>K\u0131saca ifade etmek gerekirse, UMA 2.0 kapsam\u0131nda access token ve RPT birbirini tamamlayan iki farkl\u0131 roldedir diyebiliriz. Access token, kullan\u0131c\u0131n\u0131n kim oldu\u011funu kan\u0131tlar, yani sisteme <em>-ben \u015fu kullan\u0131c\u0131y\u0131m-<\/em> diyerek bir kimlik do\u011frulama sa\u011flar. Ancak kimli\u011fin do\u011frulanmas\u0131 tek ba\u015f\u0131na bir kayna\u011fa eri\u015fim izni vermeyece\u011finden yetkilendirme s\u00fcre\u00e7lerinde yeterli de\u011fildir. Kullan\u0131c\u0131, belirli bir resource&#8217;a eri\u015fmek isterse, sistem bu talebi ayr\u0131ca de\u011ferlendirir ve uygun g\u00f6r\u00fcrse RPT \u00fcretir. RPT, art\u0131k kullan\u0131c\u0131n\u0131n hangi kayna\u011fa, hangi i\u015flemlerle eri\u015febilece\u011fini a\u00e7\u0131k\u00e7a belirten yetkiyi temsil eder. Bu y\u00fczden ak\u0131\u015fta \u00f6nce access token al\u0131n\u0131r, ard\u0131ndan gerekirse RPT \u00fcretilir ve b\u00f6ylece ger\u00e7ek yetkilendirme karar\u0131 RPT \u00fczerinden sa\u011flanm\u0131\u015f olur.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 2 | <span style=\"color:#877572;\">Permission Ticket neden \u00fcretilir?<\/span><\/summary>\n<blockquote><p><em>\u0130zin yoksa neden permission ticket \u00fcretiliyor?<\/em><\/p><\/blockquote>\n<p>UMA 2.0 i\u00e7inde izin yokken permission ticket \u00fcretilmesinin sebebi, iste\u011fi direkt reddetmek yerine bir izin talebi s\u00fcreci ba\u015flatmakt\u0131r. Yani kullan\u0131c\u0131 o anda yetkili olmasa bile sistem bu talebi kay\u0131t alt\u0131na al\u0131r, resource sahibi ya da ilgili policy&#8217;ler bu talebi sonradan de\u011ferlendirebilir ve e\u011fer uygun g\u00f6r\u00fcl\u00fcrse kullan\u0131c\u0131 tekrar geldi\u011finde RPT alarak eri\u015fim kazanabilir. B\u00f6ylece sistem statik <em style=\"font-size:14px;\">izin yoksa s\u00fcreci 403 ile sonland\u0131r<\/em> yakla\u015f\u0131m\u0131 yerine daha dinamik ve y\u00f6netilebilir bir yetkilendirme ak\u0131\u015f\u0131 sunmu\u015f olur.<\/p>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 3 | <span style=\"color:#877572;\">Resource ve Scope kavramlar\u0131 nas\u0131l tasarlanmal\u0131d\u0131r?<\/span><\/summary>\n<p>Resource scope tasar\u0131m\u0131 m\u00fcmk\u00fcn mertebe sade ve dengeli olmal\u0131d\u0131r. Resource&#8217;lar her bir veri kayd\u0131n\u0131 tek tek temsil edecek kadar detayl\u0131 de\u011fil, mant\u0131kl\u0131 gruplar halinde tan\u0131mlanmal\u0131, scope&#8217;lar ise gereksiz \u00e7e\u015fitlili\u011fe ka\u00e7madan <em>read<\/em>, <em>write<\/em>, <em>delete<\/em> gibi temel aksiyonlarla s\u0131n\u0131rland\u0131r\u0131lmal\u0131d\u0131r. \u00c7\u00fcnk\u00fc bu yakla\u015f\u0131m, hem token&#8217;lar\u0131n \u015fi\u015fmesini engeller hem de policy&#8217;lerin daha anla\u015f\u0131l\u0131r, y\u00f6netilebilir ve performansl\u0131 \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 4 | <span style=\"color:#877572;\">Policy olu\u015ftururken nelere dikkat etmeliyiz?<\/span><\/summary>\n<p>Policy tasarlarken kurallar\u0131n m\u00fcmk\u00fcn oldu\u011funca basit, deterministik ve tek bir amaca odakl\u0131 olmas\u0131 tavsiye edilmektedir. Her policy tek bir i\u015fi \u00e7\u00f6zmeli, m\u00fcmk\u00fcnse token i\u00e7inde claim&#8217;ler \u00fczerinden \u00e7al\u0131\u015fmal\u0131 ve karma\u015f\u0131k i\u015flemlerden m\u00fcmk\u00fcn mertebe ka\u00e7\u0131nmal\u0131d\u0131r. Yani anlayaca\u011f\u0131n\u0131z klasik yaz\u0131l\u0131msal ilkelerdeki hassasiyet, policy&#8217;lerde de ge\u00e7erlili\u011fini korumaktad\u0131r.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 5 | <span style=\"color:#877572;\">UMA&#8217;y\u0131 hangi durumlarda kullanmak mant\u0131kl\u0131d\u0131r?<\/span><\/summary>\n<p>UMA 2.0 \u00f6zellikle kullan\u0131c\u0131lar aras\u0131 veri payla\u015f\u0131m\u0131n\u0131n oldu\u011fu ve izinlerin statik rollerle de\u011fil dinamik s\u00fcre\u00e7lerle belirlendi\u011fi durumlarda daha anlaml\u0131d\u0131r. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n kendi dosyas\u0131n\u0131 ba\u015fkalar\u0131yla payla\u015fabilmesi, eri\u015fim talebinde bulunulup sonradan onay verilmesi veya yetkilerin ge\u00e7ici olarak devredilmesi gibi senaryolarda UMA ciddi bir esneklik sa\u011flamakta, ancak <em>admin\/user<\/em> gibi basit ayr\u0131mlar\u0131n yeterli oldu\u011fu sistmelerde gereksiz karma\u015f\u0131kl\u0131\u011fa sebebiyet vermektedir.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 6 | <span style=\"color:#877572;\">Her request&#8217;te yetkilendirmeyle ilgili durumu Keycloak&#8217;a m\u0131 soraca\u011f\u0131m?<\/span><\/summary>\n<p>Hay\u0131r, bu sistemi \u00f6ld\u00fcr\u00fcr. UMA&#8217;da al\u0131nan RPT cache&#8217;lenmeli ve m\u00fcmk\u00fcn oldu\u011funca backend taraf\u0131nda do\u011frulanmal\u0131d\u0131r. Aksi halde her istekte ekstra roundtrip performans darbo\u011faz\u0131 ka\u00e7\u0131n\u0131lmazd\u0131r!<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 7 | <span style=\"color:#877572;\">RPT&#8217;yi do\u011frulamazsak ne olur?<\/span><\/summary>\n<p>Sistem \u00e7\u00f6ker \ud83d\ude42 \u00c7\u00fcnk\u00fc direkt client taraf\u0131na g\u00fcvenilmi\u015f olunur. Bu y\u00fczden RPT mutlaka backend taraf\u0131nda validate edilmeli ve i\u00e7indeki permission&#8217;lar ger\u00e7ekten kontrol edilmelidir.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 8 | <span style=\"color:#877572;\">Permission Explosion (\u0130zin Patlamas\u0131) nas\u0131l \u00f6nlenir?<\/span><\/summary>\n<p>Her resource + scope kombinasyonunu ayr\u0131 ayr\u0131 \u00fcretirseniz sistem \u00e7\u00f6ker. Bunun yerine genelle\u015ftirilmi\u015f resource&#8217;lar + dinamik policy&#8217;ler kullan\u0131lmal\u0131d\u0131r. Tabi bu durumun pratik d\u00fczlemde daha net anla\u015f\u0131laca\u011f\u0131 a\u015fikard\u0131r \ud83d\ude09<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 9 | <span style=\"color:#877572;\">UMA ger\u00e7ekten gerekli mi, yoksa overengineering mi?<\/span><\/summary>\n<p>E\u011fer sistemde kullan\u0131c\u0131lar aras\u0131 etkile\u015fim yoksa ve izinler statikse y\u00fcksek ihtimal overengineering yap\u0131lmaktad\u0131r. UMA 2.0 ancak dinamik yetki ak\u0131\u015f\u0131 olan senaryolar i\u00e7in anlaml\u0131d\u0131r.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 10 | <span style=\"color:#877572;\">Authorization ile business logic s\u0131n\u0131r\u0131 nerede ba\u015flamal\u0131, nerede bitmelidir?<\/span><\/summary>\n<p>En kritik ayr\u0131mlardan birisi de budur diyebiliriz. Keycloak sadece <em>-eri\u015febilir mi?-<\/em> sorusunu cevaplamal\u0131d\u0131r&#8230; <em>-Ne yapmal\u0131?-<\/em> sorusu ise uygulama logic&#8217;inde kalmal\u0131d\u0131r&#8230; Aksi taktirde t\u00fcm i\u015f kurallar\u0131 Keycloak&#8217;a g\u00f6m\u00fcl\u00fcrse sistem kontrol edilemez hale gelecektir.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 11 | <span style=\"color:#877572;\">Eventual consistency problemi ya\u015fan\u0131l\u0131r m\u0131?<\/span><\/summary>\n<p>Muhtemelen&#8230; \u00c7\u00fcnk\u00fc token (\u00f6zellikle RPT) \u00fcretildikten sonra i\u00e7indeki izinler bir s\u00fcre ge\u00e7erli kalacakt\u0131r. Bu y\u00fczden bir kullan\u0131c\u0131dan izin kald\u0131r\u0131lsa bile eski token ile bir s\u00fcre eri\u015fim devam edecektir. Bunu \u00e7\u00f6zmek i\u00e7in token \u00f6mr\u00fc k\u0131sa tutulmal\u0131 ve re-check mekanizmas\u0131 kurulmal\u0131d\u0131r.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 12 | <span style=\"color:#877572;\">Revocation (izin geri alma) nas\u0131l y\u00f6netilir?<\/span><\/summary>\n<p>UMA&#8217;da bu kritik bir problemdir. \u0130zin geri al\u0131nd\u0131\u011f\u0131nda eski RPT&#8217;ler hala ge\u00e7erli olabilir, bu y\u00fczden ya token s\u00fcresi k\u0131sa tutulmal\u0131 ya da kritik i\u015flemlerde backend taraf\u0131nda ekstradan kontroller sa\u011flanmal\u0131d\u0131r.<br \/>\n<\/details>\n<details style=\"font-size:14px;\">\n<summary style=\"color:#BA8073;\">Soru 13 | <span style=\"color:#877572;\">Policy de\u011fi\u015firse mevcut RPT&#8217;ler ne olacak?<\/span><\/summary>\n<p>Asl\u0131nda bunu \u00f6nceki sorularda cevapland\u0131rm\u0131\u015f bulunuyoruz&#8230; RPT, verilmi\u015f bir izne kar\u015f\u0131l\u0131k gelmektedir. Haliyle policy de\u011fi\u015fse bile token s\u00fcresi dolana kadar ge\u00e7erlili\u011fini koruyacakt\u0131r. Bu y\u00fczden s\u00fcrekli vurgulad\u0131\u011f\u0131m\u0131z gibi k\u0131sa \u00f6m\u00fcrl\u00fc token kullanman\u0131n yan\u0131nda gerekti\u011fi noktalarda token invalidation uygulanmas\u0131 da gerekmektedir.<br \/>\n<\/details>\n<p><\/p>\n<h4><span class=\"ez-toc-section\" id=\"Keycloak_AspNET_Core_%E2%86%92_Policy-Based_Authorization\"><\/span>Keycloak + Asp.NET Core \u2192 Policy-Based Authorization<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Evet&#8230; Art\u0131k konuya dair pratik dokunu\u015flara ge\u00e7ebiliriz. Tabi ilk olarak Keycloak e\u015fli\u011finde Asp.NET Core&#8217;da <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/policy-based-authorization\/\" target=\"_blank\">Policy-Based Authorization<\/a>&#8216;\u0131 ele alal\u0131m istiyorum. Bunun nedeni, Asp.NET Core&#8217;daki politika yap\u0131lanmas\u0131n\u0131n statik veya yar\u0131-dinamik kontroller e\u015fli\u011finde yetkilendirme davran\u0131\u015f\u0131n\u0131 sa\u011fl\u0131yor olu\u015fudur. Bu yakla\u015f\u0131mda, token&#8217;dan gelen bilgilerle belirli davran\u0131\u015fsal \u015fartlar kontrol edilerek endpoint&#8217;lere eri\u015fim s\u0131n\u0131rland\u0131rmalar\u0131 getirilebilmektedir. \u015e\u00f6yle ki; <code>application-client<\/code> ad\u0131nda <em>Direct access grants<\/em> ak\u0131\u015f\u0131n\u0131 destekleyen bir client&#8217;\u0131m\u0131z olsun. Bu client&#8217;tan al\u0131nan token ile a\u015fa\u011f\u0131daki gibi bir politika tabanl\u0131 kontrol sa\u011flanabilir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\nbuilder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)\r\n    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =&gt;\r\n    {\r\n        options.Authority = &quot;http:\/\/127.0.0.1:8080\/realms\/master&quot;;\r\n        options.Audience = &quot;account&quot;;\r\n        options.RequireHttpsMetadata = false;\r\n\r\n        options.Events = new JwtBearerEvents\r\n        {\r\n            OnTokenValidated = context =&gt;\r\n            {\r\n                var identity = (ClaimsIdentity)context.Principal!.Identity!;\r\n                var realmAccess = context.Principal.FindFirst(&quot;realm_access&quot;)?.Value;\r\n\r\n                if (realmAccess != null)\r\n                {\r\n                    var doc = JsonDocument.Parse(realmAccess);\r\n                    if (doc.RootElement.TryGetProperty(&quot;roles&quot;, out var roles))\r\n                        foreach (var role in roles.EnumerateArray())\r\n                            identity.AddClaim(new Claim(ClaimTypes.Role, role.GetString()!));\r\n                }\r\n\r\n                return Task.CompletedTask;\r\n            }\r\n        };\r\n\r\n        options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters\r\n        {\r\n            RoleClaimType = ClaimTypes.Role,\r\n            NameClaimType = ClaimTypes.Name\r\n        };\r\n    });\r\n\r\nbuilder.Services.AddAuthorization(options =&gt;\r\n{\r\n    options.AddPolicy(&quot;AdminOnly&quot;, policy =&gt;\r\n    {\r\n        policy.RequireAuthenticatedUser()\r\n              .RequireClaim(ClaimTypes.Role, &quot;admin&quot;);\r\n    });\r\n});\r\n.\r\n.\r\n.\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-2.png\" alt=\"\" width=\"222\" height=\"285\" class=\"alignleft size-full wp-image-28609\" \/><\/a>Tabi burada, 36 ile 43. sat\u0131r aral\u0131\u011f\u0131nda olu\u015fturulan politika gere\u011fi payload&#8217;daki <code>realm_access<\/code> alan\u0131ndaki rollerin de\u011ferlendirilmesi gerekmektedir. Ancak, mimaride bir obje i\u00e7erisindeki dizin i\u00e7inde arama yapacak k\u0131sa yol olmad\u0131\u011f\u0131 i\u00e7in 12 ile 27. sat\u0131r aral\u0131\u011f\u0131nda ilgili alandaki roller elde edilerek identity&#8217;e <code>ClaimTypes.Role<\/code> type&#8217;\u0131 kar\u015f\u0131l\u0131\u011f\u0131nda verilmektedir, ki <code>AdminOnly<\/code> politikas\u0131nda, istek g\u00f6nderen kullan\u0131c\u0131n\u0131n <code>admin<\/code> rol\u00fcne sahip olup olmad\u0131\u011f\u0131 de\u011ferlendirilebilsin.<\/p>\n<p>Burada ekstradan 12 ile 27. sat\u0131r aral\u0131\u011f\u0131ndaki claim ay\u0131klama i\u015flemini a\u015fa\u011f\u0131daki gibi harici bir transformation s\u0131n\u0131f\u0131nda y\u00fcr\u00fctebilir ve b\u00f6ylece daha temiz bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirebiliriz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class KeycloakRolesTransformer : IClaimsTransformation\r\n    {\r\n        public Task&lt;ClaimsPrincipal&gt; TransformAsync(ClaimsPrincipal principal)\r\n        {\r\n            var identity = (ClaimsIdentity)principal.Identity!;\r\n            var realmAccess = identity.FindFirst(&quot;realm_access&quot;);\r\n\r\n            if (realmAccess is not null)\r\n            {\r\n                var json = JsonDocument.Parse(realmAccess.Value);\r\n                if (json.RootElement.TryGetProperty(&quot;roles&quot;, out var roles))\r\n                    foreach (var role in roles.EnumerateArray())\r\n                    {\r\n                        var r = role.GetString();\r\n                        if (!string.IsNullOrEmpty(r))\r\n                            identity.AddClaim(new Claim(ClaimTypes.Role, r));\r\n                    }\r\n            }\r\n\r\n            return Task.FromResult(principal);\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddScoped&lt;IClaimsTransformation, KeycloakRolesTransformer&gt;();\r\n<\/pre>\n<\/div>\n<p>\u0130\u015fte bu kadar&#8230;<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Keycloak_AspNET_Core_%E2%86%92_Resource-Based_Authorization_RBA\"><\/span>Keycloak + Asp.NET Core \u2192 Resource-Based Authorization (RBA)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>\u015eimdi de esas konumuz olan UMA 2.0&#8217;\u0131n davran\u0131\u015f\u0131na daha yak\u0131n olan Resource-Based Authorization&#8217;\u0131 tecr\u00fcbe edelim. Tabi \u00f6ncelikle ne oldu\u011funu izah edelim&#8230;<\/p>\n<p><strong>Resource-Based Authorization Nedir?<\/strong><br \/>\nResource-Based Authorization&#8217;\u0131n ne oldu\u011funu anlayabilmek i\u00e7in \u00f6ncelikle normal authorization yap\u0131lanmas\u0131n\u0131 anlamland\u0131rmam\u0131z gerekmektedir. Malumunuz, normal authorization <em>-bu user admin mi?-<\/em> \u015feklinde soru sorar ve evet\/hay\u0131r mant\u0131\u011f\u0131nda davran\u0131\u015f sergiler. Resource-Based Authorization&#8217;da ise sorunun mahiyeti biraz de\u011fi\u015fecektir ve <em>-bu user bu spesifik kayna\u011fa (resource) eri\u015febilir mi?-<\/em> formuna b\u00fcr\u00fcnecektir. Bu kaynak kullan\u0131c\u0131n\u0131n kendi olu\u015fturdu\u011fu postu ya da sipari\u015fi olabilir. Yani anlayaca\u011f\u0131n\u0131z, eri\u015filmesi gereken resource bazl\u0131 bir ko\u015ful ortaya koyulmas\u0131 gereken senaryolarda bu yakla\u015f\u0131m olduk\u00e7a idealdir.<\/p>\n<p>\u015eimdi bu mant\u0131kta bir authorization \u00e7al\u0131\u015fmas\u0131 i\u00e7in a\u015fa\u011f\u0131daki gibi yap\u0131lar\u0131n tan\u0131mlanmas\u0131 gerekmektedir:<\/p>\n<ul style=\"font-size:14px;\">\n<li><em style=\"color:green;\">Requirement olu\u015fturulmal\u0131d\u0131r<\/em><br \/>\nBu sa\u011flanmas\u0131 beklenen ko\u015fulu temsil eden bir s\u0131n\u0131ft\u0131r. Ya da bir ba\u015fka deyi\u015fle kural\u0131n ad\u0131d\u0131r. Teknik olarak <code>IAuthorizationRequirement<\/code> interface&#8217;inden implemente edilmesi gerekmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class EditPostRequirement : IAuthorizationRequirement\r\n    {\r\n    }\r\n<\/pre>\n<\/div>\n<p>Bu s\u0131n\u0131f\u0131n i\u00e7eri\u011finin dolu olmas\u0131 elzem de\u011fildir. Zahiren bak\u0131ld\u0131\u011f\u0131 zaman  bir kullan\u0131c\u0131n\u0131n post edit&#8217;leyebilmesi i\u00e7in sa\u011flamas\u0131 gereken \u015fart\u0131 ifade etti\u011fi g\u00f6r\u00fclmektedir. Ki unutulmamal\u0131d\u0131r ki requirement s\u0131n\u0131flar\u0131nda hi\u00e7bir logic bulunmamaktad\u0131r!<\/p>\n<p>As\u0131l i\u015f handler s\u0131n\u0131f\u0131ndad\u0131r&#8230;\n<\/li>\n<li><em style=\"color:green;\">Handler olu\u015fturulmal\u0131d\u0131r<\/em><br \/>\nHandler, bir requirement&#8217;\u0131n ger\u00e7ekten sa\u011flan\u0131p sa\u011flanmad\u0131\u011f\u0131n\u0131 kontrol eden karar mekanizmas\u0131d\u0131r. <code>AuthorizationHandler&lt;TRequirement, TResource&gt;<\/code> abstract class&#8217;\u0131ndan implemente edilmesi gerekmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class EditPostHandler : AuthorizationHandler&lt;EditPostRequirement, Post&gt;\r\n    {\r\n        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EditPostRequirement requirement, Post resource)\r\n        {\r\n            \/\/ClaimTypes.NameIdentifier : sub\r\n            if (resource.OwnerId.ToString() == context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value)\r\n                context.Succeed(requirement);\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, resource olan Post&#8217;un editlenme s\u00fcrecinde ilgili kullan\u0131c\u0131ya ait olup olmad\u0131\u011f\u0131 <code>EditPostRequirement<\/code>&#8216;\u0131n \u00f6zelinde de\u011ferlendirilmektedir.\n<\/li>\n<li><em style=\"color:green;\">IoC Container&#8217;a eklenmelidir<\/em><br \/>\nHandler s\u0131n\u0131f\u0131n\u0131n i\u015flevsel olabilmesi i\u00e7in IoC Container&#8217;a eklenmesi gerekmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddScoped&lt;IAuthorizationHandler, EditPostHandler&gt;();\r\n<\/pre>\n<\/div>\n<\/li>\n<li><em style=\"color:green;\">Ve gereken noktada kullan\u0131lmal\u0131d\u0131r<\/em><br \/>\nResource-Based Authorization, \u00e7o\u011funlukla ne <code>Authorize<\/code> attribute&#8217;u ile ne de <code>RequireAuthorization<\/code> metodu ile de\u011fil \u00e7o\u011funlukla kod i\u00e7erisinde (imperative) kontrol sa\u011flamaktad\u0131r.<\/p>\n<p>\u015e\u00f6yle ki; <code>Authorize<\/code> ve <code>RequireAuthorization<\/code> yap\u0131lar\u0131, request bazl\u0131 \u00e7al\u0131\u015fmakta ve sadece User \u00fczerinden karar vermektedirler. Haliyle resource nedir bilmezler. Resource-Based Authorization&#8217;da ise hem user hem resource birlikte de\u011ferlendirilmekte ve kontrol runtime&#8217;da, veri \u00e7ekildikten sonra ger\u00e7ekle\u015ftirilmektedir. Bu y\u00fczden genelde<\/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;\">await _authorizationService.AuthorizeAsync(User, resource, requirement);<br \/>\n<\/strong>\n<\/div>\n<p>\u015feklinde kullan\u0131lmaktad\u0131r. Dolay\u0131s\u0131yla a\u015fa\u011f\u0131daki gibi bir kullan\u0131m durumu s\u00f6z konusu olacakt\u0131r:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapPut(&quot;\/post-edit&quot;, async (IAuthorizationService authorizationService, HttpContext httpContext) =&gt;\r\n{\r\n    Post post = new()\r\n    {\r\n        OwnerId = new Guid(&quot;af3787e6-1c79-4ba4-a935-442851a4c529&quot;)\r\n    };\r\n\r\n    var result = await authorizationService.AuthorizeAsync(httpContext.User, post, new EditPostRequirement());\r\n\r\n    if (!result.Succeeded)\r\n        return Results.Forbid();\r\n\r\n    return Results.Ok();\r\n});\r\n<\/pre>\n<\/div>\n<p>Ama burada kritik bir nokta var. O da <code>Authorize<\/code> ve <code>RequireAuthorization<\/code> yap\u0131lar\u0131n\u0131n yine de g\u00f6zden ka\u00e7\u0131r\u0131lmamas\u0131, yani kullan\u0131lmas\u0131 gereklili\u011fidir. Bu yap\u0131lar, kullan\u0131c\u0131n\u0131n login olup olmad\u0131\u011f\u0131n\u0131 garanti eder. B\u00f6ylece zaten token&#8217;\u0131 olmayan bir kullan\u0131c\u0131n\u0131n endpoint&#8217;e eri\u015fememesi sa\u011flanarak ideal davran\u0131\u015f g\u00f6sterilmi\u015f olur. Ha kimli\u011fi do\u011frulanm\u0131\u015f kullan\u0131c\u0131n\u0131n bu kayna\u011fa eri\u015fip eri\u015fmeyece\u011fi ise art\u0131k bu kontrol\u00fcn tekelindedir&#8230;\n<\/li>\n<\/ul>\n<p>Evet&#8230; Resource-Based Authorization&#8217;da bundan ibarettir&#8230;<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Keycloak_AspNET_Core_%E2%86%92_UMA_20\"><\/span>Keycloak + Asp.NET Core \u2192 UMA 2.0<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Art\u0131k nihai olarak esas konumuzla pratik y\u00fczle\u015fmeye geldik diyebiliriz&#8230;<\/p>\n<p>Yukar\u0131daki Resource-Based Authorization yakla\u015f\u0131m\u0131nda kimin hangi kayna\u011fa eri\u015fece\u011fi belirlenmektedir. Bunu yaparken, kurallar kodda ya da policy&#8217;de olacak \u015fekilde backend&#8217;de tan\u0131mlama ger\u00e7ekle\u015ftirdik. Yani t\u00fcm kontrol tamamen yaz\u0131lan authorization logic&#8217;te tutulmaktad\u0131r.<\/p>\n<p>UMA 2.0&#8217;da ise kaynak sahibi, kimin neye eri\u015febilece\u011fine kendisi karar verecektir. Bunda ise yetkiyi uygulama de\u011fil, resource owner y\u00f6netecektir. Haliyle dinamik olarak yetki de\u011fi\u015fikli\u011fi ve kontrol\u00fc sa\u011flanabilir.<\/p>\n<div style=\"display:flex;gap:10px;\">\n<div style=\"flex:1;border:1px solid #ccc;padding:10px;\">\n    <strong>Resource-Based Authorization<\/strong><\/p>\n<div style=\"font-size:14px;\">\n<ul>\n<li>Bu kullan\u0131c\u0131 bu document&#8217;in owner&#8217;\u0131 m\u0131?<\/li>\n<li>Bu user bu resource&#8217;a ait mi?<\/li>\n<li>Bu token&#8217;a sahip ki\u015fi, \u015fu scope&#8217;lara eri\u015febilir.<\/li>\n<\/ul>\n<\/div>\n<div style=\"font-size:15px;text-align:center;\">coarse-grained, yani daha az detay, daha genel bir yakla\u015f\u0131m&#8230;<\/div>\n<\/p><\/div>\n<div style=\"flex:1;border:1px solid #ccc;padding:10px;\">\n    <strong>UMA 2.0<\/strong><\/p>\n<div style=\"font-size:14px;\">\n<ul>\n<li>Ahmet bu dosyay\u0131 g\u00f6rebilir.<\/li>\n<li>Mehmet sadece okuyabilir.<\/li>\n<li>\u015euayip, Hilmi&#8217;nin &#8220;123&#8221; numaral\u0131 faturas\u0131na (resource&#8217;una\/kayna\u011f\u0131na) <u>okuma<\/u> yapabilsin mi?<\/li>\n<\/ul>\n<\/div>\n<div  style=\"font-size:15px;text-align:center;\">fine-grained, yani daha fazla detay, daha hassas yakla\u015f\u0131m&#8230;<\/div>\n<\/p><\/div>\n<\/div>\n<blockquote style=\"font-size:14px;\"><p><em>OAuth 2.0&#8217;da karar\u0131 sunucu verirken, UMA&#8217;da ise kaynak sahibi verir, Keycloak ise bu karar\u0131 uygular.<\/em><\/p><\/blockquote>\n<p>\u015eimdi UMA 2.0&#8217;\u0131 uygulayabilmek i\u00e7in ad\u0131m ad\u0131m hem Keycloak&#8217;da hem de uygulama taraf\u0131nda hassas \u00e7al\u0131\u015fmalar ger\u00e7ekle\u015ftirmemiz gerekmektedir. Bu yetkilendirme yakla\u015f\u0131m\u0131n\u0131 tam olarak kurgulayabilmek i\u00e7in burada yapaca\u011f\u0131m\u0131z yap\u0131land\u0131rmalar olduk\u00e7a \u00f6nem arz etmektedir.<\/p>\n<p>Tabi bu yap\u0131land\u0131rmalara ge\u00e7meden \u00f6nce UMA&#8217;n\u0131n getirdi\u011fi konseptteki terminolik kavramlar\u0131 masaya yat\u0131rmakta fayda g\u00f6rmekteyim;<\/p>\n<table style=\"border-collapse:collapse;font-family:Arial,sans-serif;font-size:13px;max-width:500px;\">\n<tr>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;\">Kavram<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;\">A\u00e7\u0131klama<\/th>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Resource Owner<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Kayna\u011f\u0131n sahibi (\u00f6rn: Hilmi, kendi faturalar\u0131n\u0131n sahibi)<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Resource Server (RS)<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">API&#8217;nin kendisi \u2014 kaynaklar\u0131 koruyan sunucu<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Authorization Server (AS)<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">Keycloak \u2014 kimin neye eri\u015febilece\u011fine karar veren<\/td>\n<\/tr>\n<\/table>\n<p>Bunlar\u0131n yan\u0131nda UMA&#8217;y\u0131 uygularken her ad\u0131mda kar\u015f\u0131m\u0131za \u00e7\u0131kabilecek \u00fc\u00e7 token yap\u0131s\u0131n\u0131 da tekrar \u00f6zetleyip notumuzu alal\u0131m;<\/p>\n<table style=\"border-collapse:collapse;font-family:Arial,sans-serif;font-size:13px;max-width:750px;\">\n<tr>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;\">Token<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;\">A\u00e7\u0131klama<\/th>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;vertical-align: top;\">PAT (Protection API Token)<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">\n<ul>\n<li>Resource Server&#8217;\u0131n (API&#8217;nin) Keycloak&#8217;a <em>-ben buyum-<\/em> demek i\u00e7in kulland\u0131\u011f\u0131 token&#8217;d\u0131r.<\/li>\n<li>API, Keycloak&#8217;a resource kaydetmek i\u00e7in bu token&#8217;\u0131 kullanmaktad\u0131r.<\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/client-credentials\/\" target=\"_blank\">Client Credentials grant<\/a> ile al\u0131n\u0131r (kullan\u0131c\u0131 yok, makine-makine)<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;vertical-align: top;\">Permission Ticket<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">\n<ul>\n<li><em>-Bu kayna\u011fa eri\u015fmek istiyorum-<\/em> talebinin makbuzudur.<\/li>\n<li>RS (API), client&#8217;a <em>-git Keycloak&#8217;tan bununla izin al-<\/em> der.<\/li>\n<li>Tek kullan\u0131ml\u0131kd\u0131r, k\u0131sa \u00f6m\u00fcrl\u00fcd\u00fcr.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;vertical-align: top;\">RPT (Requesting Party Token)<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left;\">\n<ul>\n<li>Permission Ticket&#8217;\u0131 Keycloak&#8217;a g\u00f6t\u00fcr\u00fcnce al\u0131nan as\u0131l yetki token&#8217;\u0131d\u0131r.<\/li>\n<li>\u0130\u00e7inde hangi kayna\u011fa hangi scope ile eri\u015filebildi\u011fi yazmaktad\u0131r.<\/li>\n<li>API bunu do\u011frular ve eri\u015fime izin verir ya da vermez.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/table>\n<p>Hadi ba\u015flayal\u0131m&#8230;<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong>Ad\u0131m 1<\/strong> <em style=\"color:green;\">(Resource Server Client Olu\u015fturma)<\/em><br \/>\n\u0130lk olarak Asp.NET Core uygulamam\u0131z i\u00e7in Keycloak&#8217;da bir kimlik edas\u0131nda client olu\u015fturaca\u011f\u0131z. Keycloak bu client \u00fczerinden kaynak ve izin tan\u0131mlar\u0131n\u0131 tutacakt\u0131r.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-3.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"377\" height=\"170\" class=\"aligncenter size-full wp-image-28617\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-3.png 377w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-3-300x135.png 300w\" sizes=\"auto, (max-width: 377px) 100vw, 377px\" \/><\/a>Olu\u015fturulacak bu client&#8217;\u0131n ayarlar\u0131 a\u015fa\u011f\u0131daki gibi olacakt\u0131r;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-4.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"660\" height=\"163\" class=\"aligncenter size-full wp-image-28618\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-4.png 660w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-4-300x74.png 300w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/a>Buradaki yap\u0131land\u0131rmalardan bahsetmemiz gerekirse e\u011fer;<\/p>\n<ul>\n<li><strong><a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/client-credentials\/\" target=\"_blank\">Client authentication<\/a><\/strong>: Bu a\u00e7\u0131k oldu\u011fu s\u00fcrece client Keycloak&#8217;a kendini tan\u0131tmak mecburiyetindedir. Client ID ve Client Secret de\u011ferlerini \u00fcretir. Haliyle bir <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/confidential-client\/\" target=\"_blank\">confidential client<\/a> \u00fcretecektir.<\/li>\n<li><strong>Authorization<\/strong>: Bu ayar, Keycloak&#8217;da Authorization Services&#8217;\u0131n kapsam\u0131nda olan policy, permission vs. gibi \u00f6zellikleri a\u00e7maktad\u0131r. UMA 2.0 i\u00e7in \u015fart bir yap\u0131land\u0131rmad\u0131r!<\/li>\n<li><strong>Standard flow<\/strong>: <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/openiddict-authorization-code-flow\/\" target=\"_blank\">Authorization Code Flow<\/a>&#8216;u sa\u011flar. <\/li>\n<li><strong>Direct access grants<\/strong>: <a href=\"https:\/\/www.gencayyildiz.com\/blog\/keycloak-asp-net-core-ile-direct-grant-flow-authentication-8\/\" target=\"_blank\">Resource Owner Password Credentials<\/a>&#8216;\u0131 sa\u011flar.<\/li>\n<\/ul>\n<p>Sonra a\u015fa\u011f\u0131daki yap\u0131land\u0131rmalarla  client olu\u015fturulmal\u0131d\u0131r.<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:14px;white-space:pre;line-height:0.8;padding:12px;\">\nRoot URL:            https:\/\/localhost:7086<br \/>\nHome URL:            https:\/\/localhost:7086<br \/>\nValid redirect URIs: https:\/\/localhost:7086\/*<br \/>\nWeb origins:         *\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 2<\/strong> <em style=\"color:green;\">(Authorization Ayarlar\u0131n\u0131 Yap\u0131land\u0131rma)<\/em><br \/>\n\u015eimdi de olu\u015fturdu\u011fumuz client&#8217;\u0131n authorization ayarlar\u0131n\u0131 yap\u0131land\u0131raca\u011f\u0131z. Yani bir ba\u015fka deyi\u015fle, sadece kimlik do\u011frulama (login) de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131n\u0131n neye eri\u015febilece\u011finin sorusunu da y\u00f6netiyor olaca\u011f\u0131z.<\/p>\n<p>Bunun i\u00e7in olu\u015fturdu\u011fumuz client&#8217;\u0131n detaylar\u0131ndan &#8216;Authorization&#8217; sekmesine gelelim ve a\u015fa\u011f\u0131daki gibi yap\u0131land\u0131rmada bulunal\u0131m;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-5.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"635\" height=\"576\" class=\"aligncenter size-full wp-image-28619\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-5.png 635w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-5-300x272.png 300w\" sizes=\"auto, (max-width: 635px) 100vw, 635px\" \/><\/a><\/p>\n<ul>\n<li><strong>Policy enforcement mode (Politika Uygulama Modu)<\/strong>: Bu ayar politika uygulama modunu ayarlamam\u0131z\u0131 sa\u011flamaktad\u0131r. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere \u00fc\u00e7 se\u00e7enekten olu\u015fmaktad\u0131r;\n<ul>\n<li><u>Enforcing (Zorlay\u0131c\u0131)<\/u>: En g\u00fcvenli moddur. Policy yoksa yahut var olan policy \u015fartlar\u0131 sa\u011flanmad\u0131ysa eri\u015fim reddedilecektir.<\/li>\n<li><u>Permissive (Esnek)<\/u>: E\u011fer bu eri\u015fimi kontrol eden hi\u00e7bir policy yoksa varsay\u0131lan olarak izin verecektir. Ancak policy var ve a\u00e7\u0131k\u00e7a \u015fartlar\u0131 sa\u011flanm\u0131yorsa o taktirde eri\u015fim engellenecektir.<\/li>\n<li><u>Disabled (Kapal\u0131)<\/u>: Authorization&#8217;\u0131 tamamen devre d\u0131\u015f\u0131 b\u0131rakacakt\u0131r. Keycloak sadece login yapacakt\u0131r ancak yetki kontrol\u00fc yapmayacakt\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Decision strategy (Karar Stratejisi)<\/strong>: Birden fazla policy&#8217;nin s\u00f6z konusu oldu\u011fu senaryolarda son karar\u0131n nas\u0131l verilece\u011fini belirleyen stratejiyi yap\u0131land\u0131rmaktad\u0131r.\n<ul>\n<li><u>Unanimous (Oybirli\u011fi)<\/u>: T\u00fcm policy&#8217;lerin \u015fartlar\u0131 sa\u011flan\u0131rsa eri\u015fim olacakt\u0131r. Aralar\u0131ndan bir tane bile &#8216;deny&#8217; varsa eri\u015fim reddedilecektir.<\/li>\n<li><u>Affirmative (\u00c7o\u011funluk\/En az biri yeter)<\/u>: En az bir policy izin verirse eri\u015fim sa\u011flanacakt\u0131r. Di\u011ferleri reddetse bile izin \u00e7\u0131kabilir. Esnek senaryolarda ge\u00e7erlidir.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Remote resource management<\/strong>: Bu yap\u0131land\u0131rma a\u00e7\u0131k oldu\u011fu s\u00fcrece uygulama (API vs.) Keycloak&#8217;a ba\u011flant\u0131 sa\u011flayarak resource&#8217;lar\u0131, policy&#8217;leri ve permission&#8217;lar\u0131 dinamik olarak y\u00f6netebilecektir.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Ad\u0131m 3<\/strong> <em style=\"color:green;\">(Scope Tan\u0131mlama)<\/em><br \/>\nUMA&#8217;da scope kavram\u0131, bir kaynak \u00fczerinde yap\u0131labilecek i\u015flem t\u00fcr\u00fcn\u00fc ifade etmektedir.<\/p>\n<div style=\"\n    margin: 36px 0;\n    padding: 18px 20px;\n    border: 1px solid #c7d2fe;\n    border-radius: 6px;\n    background: #eef2ff;\n    font-family: system-ui, sans-serif;\n\"><\/p>\n<div style=\"\n        font-weight: 600;\n        color: #3730a3;\n        margin-bottom: 8px;\n    \"><br \/>\n        UMA 2.0&#8217;daki Scope vs Client Scope\n    <\/div>\n<div style=\"\n        font-size: 15px;\n        line-height: 1.7;\n        color: #1e293b;\n    \"><br \/>\nUMA 2.0&#8217;daki scope, authorization scope&#8217;dur. User-Managed Access (UMA) i\u00e7inde kullan\u0131lan bir kavramd\u0131r. Bir kaynak \u00fczerinde yap\u0131labilecek aksiyonu temsil etmektedir ve <em>-bu kullan\u0131c\u0131 bu kayna\u011f\u0131 ne yapabilir?-<\/em> sorusunu cevaplar&#8230;<\/p>\n<p>Client scope ise Keycloak i\u00e7inde OAuth\/OIDC taraf\u0131na aittir ve token i\u00e7ine hangi bilgilerin (claim&#8217;lerin) eklenece\u011fini belirlemektedir.<\/p>\n<p>UMA Scope \u2192 yetki<br \/>\nClient Scope \u2192 veri\n    <\/p><\/div>\n<\/div>\n<p>Haliyle bizler yine ilgili client&#8217;\u0131n &#8216;Authorization&#8217; \u2192 &#8216;Scopes&#8217; kombinasyonuna gelerek a\u015fa\u011f\u0131daki gibi scope&#8217;lar\u0131 olu\u015ftural\u0131m:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-6.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"629\" height=\"424\" class=\"aligncenter size-full wp-image-28620\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-6.png 629w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-6-300x202.png 300w\" sizes=\"auto, (max-width: 629px) 100vw, 629px\" \/><\/a>\n<\/li>\n<li><strong>Ad\u0131m 4<\/strong> <em style=\"color:green;\">(Resource Tan\u0131mlama)<\/em><br \/>\n\u015eimdi de Asp.NET Core uygulamam\u0131zda hangi kayna\u011f\u0131 koruma alt\u0131na almak istiyorsak onu resource olarak tan\u0131mlayaca\u011f\u0131z. Bunun i\u00e7in &#8216;Authorization&#8217; \u2192 &#8216;Resources&#8217; kombinasyonuna gelerek a\u015fa\u011f\u0131daki gibi bir resource tasarlayal\u0131m:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-7.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"516\" height=\"641\" class=\"aligncenter size-full wp-image-28621\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-7.png 516w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-7-241x300.png 241w\" sizes=\"auto, (max-width: 516px) 100vw, 516px\" \/><\/a>Buradaki yap\u0131land\u0131rmaya bakarsan\u0131z Asp.NET Core&#8217;daki <code>\/api\/documents\/{id}<\/code> endpoint&#8217;i ile bu resource&#8217;u e\u015fle\u015ftirerek, Keycloak&#8217;a hangi kayna\u011f\u0131 korumas\u0131 gerekti\u011fini ifade etmi\u015f oluyoruz. Ayr\u0131ca &#8216;<em>Authorization scopes<\/em> alan\u0131nda g\u00f6r\u00fcld\u00fc\u011f\u00fc gibi olu\u015fturdu\u011fumuz scope&#8217;lar\u0131 bu resource&#8217;la ili\u015fkilendirerek yetkisel davran\u0131\u015flar\u0131 da belirlemi\u015f oluyoruz.<\/p>\n<p>Burada ayr\u0131ca &#8216;Type&#8217; alan\u0131ndaki garip <code>urn:uma-resource-server:resources:document<\/code> de\u011ferine dikkatinizi \u00e7ekmek istiyorum. Bu format, g\u00f6z\u00fcn\u00fcz\u00fc korkutmas\u0131n&#8230; di\u011fer resource&#8217;larla bir \u00e7ak\u0131\u015fma olmamas\u0131 i\u00e7in bu \u015fekilde bir format benimsenmektedir. \u00d6zellikle farkl\u0131 ekiplerin s\u00f6z konusu oldu\u011fu microservice mimarilerde resource&#8217;lar\u0131n \u00e7ak\u0131\u015fmas\u0131 \u00e7ok tecr\u00fcbe edildi\u011fi i\u00e7in bu tarz bir isimlendirme tercih edilmektedir.<\/p>\n<p>&#8216;User-Managed Access enabled&#8217; alan\u0131 ise resource sahibinin (user) eri\u015fim kararlar\u0131na do\u011frudan dahil olaca\u011f\u0131n\u0131 belirlemektedir. Yani yetkiyi kullan\u0131c\u0131 y\u00f6netmektedir.\n<\/li>\n<li><strong>Ad\u0131m 5<\/strong> <em style=\"color:green;\">(Role &#038; User Policy&#8217;leri Tan\u0131mlama)<\/em><br \/>\nEvet&#8230; Art\u0131k s\u0131ra bir policy tan\u0131malaya gelmi\u015ftir. Policy, <em>-kim eri\u015febilir?-<\/em> sorusunun cevab\u0131d\u0131r&#8230; Bunun i\u00e7in de &#8216;Authorization&#8217; \u2192 &#8216;Policies&#8217; sekmesine gelinmesi gerekmektedir.<\/p>\n<p>Policy, a\u015fa\u011f\u0131daki gibi birka\u00e7 t\u00fcr\u00fc olan bir yap\u0131ya sahiptir:<\/p>\n<table style=\"border-collapse:collapse;width:100%;font-family:Arial,sans-serif;font-size:13px\">\n<thead>\n<tr>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;width:13%;\">Policy T\u00fcr\u00fc<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;width:50%;\">A\u00e7\u0131klama<\/th>\n<th style=\"border:1px solid #ccc;padding:6px;background:#f5f5f5;text-align:left;width:37%;\">Ne Zaman Kullan\u0131l\u0131r?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Client<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Belirli bir uygulaman\u0131n (client) eri\u015fmesine izin verir. Ya da bir ba\u015fka deyi\u015fle, belirli bir client \u00fczerinden gelen taleplere izin verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Sadece belirli servisler\/API\u2019ler eri\u015febilsin istiyorsan<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Client Scope<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Token i\u00e7indeki client scope\u2019a g\u00f6re eri\u015fim verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Token\u2019da belirli scope varsa izin ver senaryosu<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Group<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Kullan\u0131c\u0131n\u0131n ait oldu\u011fu gruba g\u00f6re karar verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Departman \/ organizasyon bazl\u0131 yetkilendirme<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Regex<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Belirli bir pattern (regex) e\u015fle\u015firse izin verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Dinamik veya string bazl\u0131 kurallar gerekti\u011finde<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Role<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Kullan\u0131c\u0131n\u0131n rol\u00fcne g\u00f6re eri\u015fim kontrol\u00fc yapar.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">En yayg\u0131n: admin, user, manager gibi roller<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Time<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Belirli zaman aral\u0131klar\u0131nda eri\u015fime izin verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Mesai saatleri, kampanya s\u00fcresi vb.<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">User<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Belirli kullan\u0131c\u0131(lar)a \u00f6zel eri\u015fim verir.<\/td>\n<td style=\"border:1px solid #ccc;padding:6px;text-align:left\">Spesifik ki\u015filere izin vermek istedi\u011finde<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Biz burada Role-Based ve User-Based olmak \u00fczere iki policy uygulayaca\u011f\u0131z. Haliyle ilk olarak Role-Based policy&#8217;le ba\u015flayal\u0131m&#8230;<\/p>\n<p><em>Role-Based Policy;<\/em><br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-8.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-8.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"759\" height=\"536\" class=\"aligncenter size-full wp-image-28623\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-8.png 759w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-8-300x212.png 300w\" sizes=\"auto, (max-width: 759px) 100vw, 759px\" \/><\/a>Burada dikkat edilirse bu politikaya uygun kullan\u0131c\u0131lar\u0131n sadece &#8216;user&#8217; rol\u00fcne sahip olup olmamas\u0131 yeterli g\u00f6r\u00fclmektedir. (Tabi \u00f6nceden Realm roles sekmesinden &#8216;user&#8217; rol\u00fcn\u00fcn olu\u015fturulmu\u015f olmas\u0131 gerekmektedir.) Burada <strong>Fetch Roles<\/strong>, kullan\u0131c\u0131n\u0131n alt (inherited) rollerinin de hesaba kat\u0131l\u0131p kat\u0131lmamas\u0131n\u0131 yap\u0131land\u0131rmaktad\u0131r. Yani bu yap\u0131land\u0131rma kapal\u0131 kald\u0131\u011f\u0131 taktirde sadece direkt atanm\u0131\u015f roller kontrol edilecektir. A\u00e7\u0131l\u0131rsa e\u011fer composite (i\u00e7 i\u00e7e) roller de dahil edilecek ve b\u00f6ylece rol hiyerar\u015fisi de \u00f6nem kazanm\u0131\u015f olacakt\u0131r. <strong>Logic<\/strong> alan\u0131 ise policy&#8217;nin sonucuna g\u00f6re nas\u0131l davran\u0131\u015f sergileyece\u011fini belirlemektedir. <em>Positive<\/em>, \u015fart sa\u011fland\u0131\u011f\u0131 s\u00fcrece eri\u015fime izin verecekken; <em>Negative<\/em> ise \u015fart sa\u011fland\u0131\u011f\u0131 taktirde eri\u015fimi reddedecektir. <em>Negative<\/em>&#8216;i blacklist gibi d\u00fc\u015f\u00fcnebilirsiniz&#8230; <em>-\u015fu role sahip olanlar asla giremesin-<\/em> mant\u0131\u011f\u0131nda bir davran\u0131\u015f i\u00e7in tercih edilebilir&#8230;<\/p>\n<p><em>User-Based Policy;<\/em><br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-9.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-9.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"323\" height=\"392\" class=\"aligncenter size-full wp-image-28625\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-9.png 323w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-9-247x300.png 247w\" sizes=\"auto, (max-width: 323px) 100vw, 323px\" \/><\/a>Burada da \u00f6rne\u011fimizi zenginle\u015ftirmek i\u00e7in kullan\u0131c\u0131n\u0131n spesifik olarak &#8216;gncy&#8217; olup olmad\u0131\u011f\u0131n\u0131 de\u011ferlendiren bir politika olu\u015fturuyoruz.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-10.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"635\" height=\"351\" class=\"aligncenter size-full wp-image-28626\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-10.png 635w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-10-300x166.png 300w\" sizes=\"auto, (max-width: 635px) 100vw, 635px\" \/><\/a>Evet&#8230; Art\u0131k iki adet politikam\u0131z haz\u0131r oldu\u011funa g\u00f6re izinleri tan\u0131mlamaya ge\u00e7ebiliriz.\n<\/li>\n<li><strong>Ad\u0131m 6<\/strong> <em style=\"color:green;\">(Permission Tan\u0131mlama)<\/em><br \/>\nPermission, \u00f6nceki ad\u0131mlarda olu\u015fturulan resource, scope ve policy \u00fc\u00e7l\u00fcs\u00fcn\u00fcn birle\u015ftirildi\u011fi noktad\u0131r. Yani; <em>-hangi kaynak i\u00e7in, hangi i\u015flemde, hangi policy ge\u00e7erlidir?-<\/em> sorusunun cevab\u0131n\u0131 verece\u011fimiz nihai noktad\u0131r. Bunun i\u00e7in &#8216;Authorization&#8217; \u2192 &#8216;Permissions&#8217; sekmesine gelinmesi gerekmektedir.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-11.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"593\" height=\"372\" class=\"aligncenter size-full wp-image-28628\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-11.png 593w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-11-300x188.png 300w\" sizes=\"auto, (max-width: 593px) 100vw, 593px\" \/><\/a>Burada dikkat ederseniz kar\u015f\u0131m\u0131za <em>Resource-Based Permission<\/em> ve <em>Scope-Based Permission<\/em> kavramlar\u0131 \u00e7\u0131kmaktad\u0131r. \u015eimdi gelin bunlar nedir izah ederek devam edelim&#8230;<\/p>\n<ul>\n<li><strong>Resource-Based Permission<\/strong>: Sadece resource&#8217;a bakan, scope&#8217;u \u00f6nemsemeyen permission t\u00fcr\u00fcd\u00fcr. Mant\u0131\u011f\u0131 salt olarak <em>-bu kayna\u011fa eri\u015fim var m\u0131?-<\/em> \u015feklindedir&#8230; Aksiyon ayr\u0131m\u0131 g\u00f6zetilmemektedir. Basit yetkilendirme s\u00fcre\u00e7lerinde tercih edilir.<\/li>\n<li><strong>Scope-Based Permission<\/strong>: Resource ile scope birlikte de\u011ferlendirilir. <em>-Bu kayna\u011f\u0131n \u015fu i\u015flemini yapabilir mi?-<\/em> tarz\u0131nda detayl\u0131 yetkilendirme s\u00fcre\u00e7lerinde kullan\u0131l\u0131r. \u00d6rne\u011fin; bir resource&#8217;a <em>read<\/em> yap\u0131labiliyor olsun ancak <em>write<\/em> ve <em>delete<\/em> yap\u0131lam\u0131yor olsun. \u0130\u015fte b\u00f6yle aksiyon bazl\u0131 kontrol gereken bir senaryoda scope-based permission&#8217;dan istifade edilebilir.<\/li>\n<\/ul>\n<blockquote><p><em>Resource permission kap\u0131y\u0131 a\u00e7arken, scope permission ise i\u00e7eride ne yap\u0131laca\u011f\u0131n\u0131 belirler&#8230;<\/em><\/p><\/blockquote>\n<p>\u015eimdi bizler UMA 2.0&#8217;a yak\u0131\u015f\u0131r seviyede scope-based permission olu\u015fturarak devam edelim&#8230;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-12.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-12.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"385\" height=\"659\" class=\"aligncenter size-full wp-image-28632\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-12.png 385w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-12-175x300.png 175w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/><\/a>Burada <em>Document Resource<\/em> kayna\u011f\u0131 \u00fczerinde, <em>read<\/em> aksiyonu (scope) i\u00e7in <em>Has User Role<\/em> politikas\u0131n\u0131n uygulanaca\u011f\u0131 tan\u0131mlanmaktad\u0131r. Tabi bu tan\u0131mda bizler i\u00e7in \u00f6nem arz eden baz\u0131 noktalar mevcuttur; <strong>Apply to resource type<\/strong>, bu permission&#8217;\u0131n tek bir resource&#8217;a m\u0131 uygulanaca\u011f\u0131, yoksa o tipteki t\u00fcm resource&#8217;lara m\u0131 uygulanaca\u011f\u0131n\u0131 ifade eden bir yap\u0131land\u0131rmad\u0131r. Kapal\u0131 oldu\u011fu taktirde, olu\u015fturulacak permission sadece se\u00e7ilen resource i\u00e7in ge\u00e7erli olacak, a\u00e7\u0131ld\u0131\u011f\u0131nda ise resource type&#8217;a g\u00f6re uygulama sa\u011flanacakt\u0131r. \u00c7ok say\u0131da ayn\u0131 tipten resource&#8217;un s\u00f6z konusu oldu\u011fu ve hepsine ayn\u0131 kural\u0131n uygulanaca\u011f\u0131 durumlarda kullan\u0131labilir. <strong>Decision Strategy<\/strong> ise birden fazla policy&#8217;nin oldu\u011fu durumlarda karar\u0131n nas\u0131l verilece\u011fini yap\u0131land\u0131rmaktad\u0131r.\n<\/li>\n<li><strong>Ad\u0131m 7<\/strong> <em style=\"color:green;\">(Postman Client Olu\u015fturma)<\/em><br \/>\nKeycloak kanad\u0131nda \u00e7o\u011fu yap\u0131land\u0131rmalar\u0131m\u0131z\u0131 tamamlam\u0131\u015f bulunuyoruz. S\u0131rada bunlar\u0131 test edebilmek i\u00e7in kullan\u0131c\u0131n\u0131n kullanaca\u011f\u0131 bir client tasarlamam\u0131z gerekmektedir. Tabi bunun i\u00e7in bizler oturup client yazmayacak, bu noktada Postman&#8217;den istifade edece\u011fiz. Haliyle Keycloak&#8217;da \u015fu konfig\u00fcrasyonlara sahip bir client olu\u015fturmam\u0131z yeterli olacakt\u0131r:<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:14px;white-space:pre;line-height:0.8;padding:12px;\">\nClient ID:              postman-client<br \/>\nClient authentication:  OFF  \u2190 (public client, secret gerekmez)<br \/>\nStandard flow:          ON<br \/>\nDirect access grants:   ON<br \/>\nValid redirect URIs:    https:\/\/oauth.pstmn.io\/v1\/callback\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 8<\/strong> <em style=\"color:green;\">(Asp.NET Core API Yap\u0131land\u0131rma)<\/em><br \/>\nEvet&#8230; Art\u0131k Asp.NET Core API k\u0131sm\u0131n\u0131 yap\u0131land\u0131rmaya ge\u00e7ebiliriz. Burada yap\u0131lmas\u0131 gereken temel i\u015flem \u00f6ncelikle konfig\u00fcrasyonel de\u011ferlerin mimariye a\u015fa\u011f\u0131daki gibi ta\u015f\u0131nmas\u0131d\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  .\r\n  .\r\n  .,\r\n  &quot;Keycloak&quot;: {\r\n    &quot;Authority&quot;: &quot;http:\/\/localhost:8080\/realms\/master&quot;,\r\n    &quot;ClientId&quot;: &quot;uma-resource-server-api&quot;,\r\n    &quot;ClientSecret&quot;: &quot;b4NkeoNJk35a9zykXGkJDxMSovyaxuIw&quot;,\r\n    &quot;TokenEndpoint&quot;: &quot;http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token&quot;,\r\n    &quot;PermissionEndpoint&quot;: &quot;http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token&quot;\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 9<\/strong> <em style=\"color:green;\">(Permission Ticket Alma)<\/em><br \/>\nKeycloak&#8217;dan permission ticket alabilmek i\u00e7in <code>UmaTokenService<\/code> isimli bir s\u0131n\u0131f olu\u015ftural\u0131m ve i\u00e7eri\u011fine a\u015fa\u011f\u0131daki \u00e7al\u0131\u015fmay\u0131 ekleyelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UmaTokenService(IHttpClientFactory httpClientFactory, IConfiguration configuration)\r\n    {\r\n        \/\/Keycloak'a -bu kaynak i\u00e7in izin bileti ver- diyen metottur.\r\n        \/\/D\u00f6nen ticket, 401 response i\u00e7inde client'a g\u00f6nderilir.\r\n        \/\/Client bu ticket'\u0131 al\u0131p Keycloak'a g\u00f6t\u00fcrerek RPT edinir.\r\n        public async Task&lt;string?&gt; GetPermissionTicketAsync(string resourceId, string scope)\r\n        {\r\n            var httpClient = httpClientFactory.CreateClient();\r\n\r\n            \/\/\u00d6nce resource server'\u0131n kendi access token'\u0131n\u0131 al\u0131yoruz.\r\n            var resourceServerToken = await GetResourceServerAccessTokenAsync(httpClient);\r\n\r\n            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;Bearer&quot;, resourceServerToken);\r\n\r\n            \/\/UMA Permission Endpoint'ine istek atarak permission ticket al\u0131yoruz.\r\n            var permissionEndpoint = $&quot;{configuration&#x5B;&quot;Keycloak:Authority&quot;]}\/authz\/protection\/permission&quot;;\r\n            var body = new&#x5B;] {\r\n                new {\r\n                    resource_id = resourceId,\r\n                    resource_scopes = new&#x5B;] { scope }\r\n                }\r\n            };\r\n            var response = await httpClient.PostAsJsonAsync(permissionEndpoint, body);\r\n            if (!response.IsSuccessStatusCode) return null;\r\n\r\n            var result = await response.Content.ReadFromJsonAsync&lt;PermissionTicketResponse&gt;();\r\n            return result.Ticket;\r\n\r\n            async Task&lt;string?&gt; GetResourceServerAccessTokenAsync(HttpClient httpClient)\r\n            {\r\n                var formData = new Dictionary&lt;string, string&gt;\r\n                {\r\n                    &#x5B;&quot;grant_type&quot;] = &quot;client_credentials&quot;,\r\n                    &#x5B;&quot;client_id&quot;] = configuration&#x5B;&quot;Keycloak:ClientId&quot;]!,\r\n                    &#x5B;&quot;client_secret&quot;] = configuration&#x5B;&quot;Keycloak:ClientSecret&quot;]!\r\n                };\r\n\r\n                var response = await httpClient.PostAsync(configuration&#x5B;&quot;Keycloak:TokenEndpoint&quot;]!, new FormUrlEncodedContent(formData));\r\n                var result = await response.Content.ReadFromJsonAsync&lt;TokenResponse&gt;();\r\n\r\n                return result?.AccessToken ?? throw new Exception(&quot;Resource server token al\u0131namad\u0131!&quot;);\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 10<\/strong> <em style=\"color:green;\">(Permission Ticket&#8217;\u0131 RPT&#8217;ye D\u00f6n\u00fc\u015ft\u00fcrme)<\/em><br \/>\n\u015eimdi de client&#8217;\u0131n elde etti\u011fi permission ticket ile Keycloak&#8217;dan RPT edinilmesini sa\u011flayacak \u00e7al\u0131\u015fmay\u0131 ekleyelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UmaTokenService(IHttpClientFactory httpClientFactory, IConfiguration configuration)\r\n    {\r\n        .\r\n        .\r\n        .\r\n\r\n        public async Task&lt;string?&gt; ExchangeForRptAsync(string userAccessToken, string permissionTicket)\r\n        {\r\n            var httpClient = httpClientFactory.CreateClient();\r\n            var formData = new Dictionary&lt;string, string&gt;\r\n            {\r\n                &#x5B;&quot;grant_type&quot;] = &quot;urn:ietf:params:oauth:grant-type:uma-ticket&quot;,\r\n                &#x5B;&quot;client_id&quot;] = configuration&#x5B;&quot;Keycloak:ClientId&quot;]!,\r\n                &#x5B;&quot;client_secret&quot;] = configuration&#x5B;&quot;Keycloak:ClientSecret&quot;]!,\r\n                &#x5B;&quot;ticket&quot;] = permissionTicket\r\n            };\r\n            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;Bearer&quot;, userAccessToken);\r\n            var response = await httpClient.PostAsync(configuration&#x5B;&quot;Keycloak:TokenEndpoint&quot;]!, new FormUrlEncodedContent(formData));\r\n\r\n            if (!response.IsSuccessStatusCode) return null;\r\n\r\n            var result = await response.Content.ReadFromJsonAsync&lt;TokenResponse&gt;();\r\n            return result?.AccessToken;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Burada <code>urn:ietf:params:oauth:grant-type:uma-ticket<\/code> de\u011feri, UMA 2.0 ak\u0131\u015f\u0131n\u0131 ba\u015flatan ve g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere standart olanlardan farkl\u0131 olan \u00f6zel bir OAuth grant type&#8217;\u0131d\u0131r! Bu grant type ile Keycloak, normal bir token de\u011fil, de\u011ferlendirilmi\u015f bir token verece\u011fini anlamaktad\u0131r!<\/p>\n<p>Ayr\u0131ca burada kullan\u0131lan access token&#8217;\u0131n kullan\u0131c\u0131 token&#8217;\u0131 oldu\u011funa dikkatinizi \u00e7ekerim!\n<\/li>\n<li><em style=\"color:purple;\">Permission Ticket &#038; RPT&#8217;yi \u0130ncelelim<\/em><br \/>\n\u015eimdi burada araya girerek Keycloak&#8217;dan edinece\u011fimiz permission ticket ve RPT&#8217;yi incelemekte fayda g\u00f6rmekteyim&#8230; <em><strong>Nesini inceleyece\u011fiz?<\/strong><\/em> diye sorarsan\u0131z e\u011fer bunlar\u0131n nas\u0131l yap\u0131ya sahip olduklar\u0131n\u0131 g\u00f6rmemiz yeterli olacakt\u0131r diye d\u00fc\u015f\u00fcn\u00fcyorum.<\/p>\n<p>Tabi, geli\u015ftirmemizin bu a\u015famas\u0131nda sizlerin permission ticket ile birlikte RPT&#8217;yi edinebilmeniz pek m\u00fcmk\u00fcn de\u011fil. Elbette ki sonraki ad\u0131mlar kapsam\u0131nda yap\u0131lmas\u0131 gereken baz\u0131 hamleler olacakt\u0131r. Lakin ben deniz, bu de\u011ferleri \u00f6ncelikli olarak elde edip yine de sizlere g\u00f6stermek istiyorum.<\/p>\n<p>\u015eimdi bakarsan\u0131z a\u015fa\u011f\u0131da hem permission ticket hem de RPT token&#8217;lar\u0131n\u0131 g\u00f6receksiniz;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-13.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-13.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"309\" height=\"357\" class=\"aligncenter size-full wp-image-28635\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-13.png 309w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-13-260x300.png 260w\" sizes=\"auto, (max-width: 309px) 100vw, 309px\" \/><\/a>Bunlar yap\u0131sal olarak esas\u0131nda birer JWT&#8217;dirler. Evet, haliyle <a href=\"https:\/\/www.jwt.io\/\" target=\"_blank\">jwt.io<\/a>&#8216;dan bunlar\u0131n i\u00e7eri\u011fine g\u00f6z atabiliriz&#8230;<\/p>\n<table>\n<thead>\n<tr>\n<th>Permission Ticket<\/th>\n<th>RPT<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left;vertical-align:top;\">\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:10px;white-space:pre;line-height:0.8;padding:12px;\">\n{<br \/>\n  &#8220;exp&#8221;: 1776953939,<br \/>\n  &#8220;iat&#8221;: 1776953879,<br \/>\n  &#8220;permissions&#8221;: [<br \/>\n    {<br \/>\n      &#8220;scopes&#8221;: [<br \/>\n        &#8220;read&#8221;<br \/>\n      ],<br \/>\n      &#8220;rsid&#8221;: &#8220;dbfb5c18-4166-4638-8e84-faff8f5f9126&#8221;<br \/>\n    }<br \/>\n  ],<br \/>\n  &#8220;jti&#8221;: &#8220;563a0953-1d31-395f-b88a-8985f8e86ab8-1776953879093&#8221;,<br \/>\n  &#8220;aud&#8221;: &#8220;http:\/\/localhost:8080\/realms\/master&#8221;,<br \/>\n  &#8220;sub&#8221;: &#8220;37577179-72d9-4fe4-90a6-84debfc17f39&#8221;,<br \/>\n  &#8220;azp&#8221;: &#8220;uma-resource-server-api&#8221;<br \/>\n}\n<\/div>\n<\/td>\n<td style=\"text-align:left;vertical-align:top;\">\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;font-size:10px;white-space:pre;line-height:0.8;padding:12px;height: 255px;overflow: auto;\">\n{<br \/>\n  &#8220;exp&#8221;: 1776953939,<br \/>\n  &#8220;iat&#8221;: 1776953879,<br \/>\n  &#8220;jti&#8221;: &#8220;ntrtna:9636c515-dd99-1d94-92ce-92349eec5f18&#8221;,<br \/>\n  &#8220;iss&#8221;: &#8220;http:\/\/localhost:8080\/realms\/master&#8221;,<br \/>\n  &#8220;aud&#8221;: &#8220;uma-resource-server-api&#8221;,<br \/>\n  &#8220;sub&#8221;: &#8220;3fe29fb3-8b9e-4714-996c-ca3c5c589935&#8221;,<br \/>\n  &#8220;typ&#8221;: &#8220;Bearer&#8221;,<br \/>\n  &#8220;azp&#8221;: &#8220;postman-client&#8221;,<br \/>\n  &#8220;sid&#8221;: &#8220;iA_VBjs0yeHZ7WgmFkcb3kES&#8221;,<br \/>\n  &#8220;acr&#8221;: &#8220;1&#8221;,<br \/>\n  &#8220;allowed-origins&#8221;: [<br \/>\n    &#8220;*&#8221;<br \/>\n  ],<br \/>\n  &#8220;realm_access&#8221;: {<br \/>\n    &#8220;roles&#8221;: [<br \/>\n      &#8220;create-realm&#8221;,<br \/>\n      &#8220;default-roles-master&#8221;,<br \/>\n      &#8220;offline_access&#8221;,<br \/>\n      &#8220;admin&#8221;,<br \/>\n      &#8220;uma_authorization&#8221;,<br \/>\n      &#8220;user&#8221;<br \/>\n    ]<br \/>\n  },<br \/>\n  &#8220;resource_access&#8221;: {<br \/>\n    &#8220;master-realm&#8221;: {<br \/>\n      &#8220;roles&#8221;: [<br \/>\n        &#8220;view-identity-providers&#8221;,<br \/>\n        &#8220;view-realm&#8221;,<br \/>\n        &#8220;manage-identity-providers&#8221;,<br \/>\n        &#8220;impersonation&#8221;,<br \/>\n        &#8220;create-client&#8221;,<br \/>\n        &#8220;manage-users&#8221;,<br \/>\n        &#8220;query-realms&#8221;,<br \/>\n        &#8220;view-authorization&#8221;,<br \/>\n        &#8220;query-clients&#8221;,<br \/>\n        &#8220;query-users&#8221;,<br \/>\n        &#8220;manage-events&#8221;,<br \/>\n        &#8220;manage-realm&#8221;,<br \/>\n        &#8220;view-events&#8221;,<br \/>\n        &#8220;view-users&#8221;,<br \/>\n        &#8220;view-clients&#8221;,<br \/>\n        &#8220;manage-authorization&#8221;,<br \/>\n        &#8220;manage-clients&#8221;,<br \/>\n        &#8220;query-groups&#8221;<br \/>\n      ]<br \/>\n    },<br \/>\n    &#8220;account&#8221;: {<br \/>\n      &#8220;roles&#8221;: [<br \/>\n        &#8220;manage-account&#8221;,<br \/>\n        &#8220;manage-account-links&#8221;,<br \/>\n        &#8220;view-profile&#8221;<br \/>\n      ]<br \/>\n    }<br \/>\n  },<br \/>\n  &#8220;authorization&#8221;: {<br \/>\n    &#8220;permissions&#8221;: [<br \/>\n      {<br \/>\n        &#8220;scopes&#8221;: [<br \/>\n          &#8220;read&#8221;<br \/>\n        ],<br \/>\n        &#8220;rsid&#8221;: &#8220;dbfb5c18-4166-4638-8e84-faff8f5f9126&#8221;,<br \/>\n        &#8220;rsname&#8221;: &#8220;Document Resource&#8221;<br \/>\n      }<br \/>\n    ]<br \/>\n  },<br \/>\n  &#8220;scope&#8221;: &#8220;profile email&#8221;,<br \/>\n  &#8220;email_verified&#8221;: false,<br \/>\n  &#8220;preferred_username&#8221;: &#8220;admin&#8221;<br \/>\n}\n<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"vertical-align:top;text-align:justify;\"><em>rsid<\/em> kayna\u011f\u0131 i\u00e7in &#8216;read&#8217; scope&#8217;una izin ticket&#8217;\u0131 istenmektedir.<\/td>\n<td style=\"vertical-align:top;text-align:justify;\">E\u011fer politikalar do\u011frultusunda \u015fartlar ge\u00e7erliyse \u00f6zel yetkilendirilmi\u015f RPT olu\u015fturulmaktad\u0131r Dikkat ederseniz <code>authorization.permissions<\/code> alan\u0131nda hangi resource&#8217;a hangi yetkinin verildi\u011fi belirtilmektedir.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li><strong>Ad\u0131m 11<\/strong> <em style=\"color:green;\">(RPT Validator Olu\u015fturma)<\/em><br \/>\n\u00c7al\u0131\u015fmalara devam edersek e\u011fer RPT i\u00e7erisinde gelen <code>authorization.permissions<\/code> alan\u0131n\u0131 okuyarak ger\u00e7ek izinleri kontrol etmemiz gerekmektedir. Bu i\u015flemi de a\u015fa\u011f\u0131daki gibi bir validator ile ger\u00e7ekle\u015ftirece\u011fiz;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class RptValidator\r\n    {\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ RPT'nin payload'\u0131n\u0131 decode edip i\u00e7indeki izinlerin istenen kayna\u011fa ve scope'a sahip olup olmad\u0131\u011f\u0131n\u0131 kontrol ediyoruz.\r\n        \/\/\/ \r\n        \/\/\/ RPT payload \u00f6rne\u011fi : \r\n        \/\/\/  \r\n        \/\/\/ {\r\n        \/\/\/   &quot;authorization&quot;: {\r\n        \/\/\/    &quot;permissions&quot;: &#x5B;\r\n        \/\/\/      {\r\n        \/\/\/        &quot;scopes&quot;: &#x5B;\r\n        \/\/\/          &quot;read&quot;\r\n        \/\/\/        ],\r\n        \/\/\/        &quot;rsid&quot;: &quot;dbfb5c18-4166-4638-8e84-faff8f5f9126&quot;,\r\n        \/\/\/        &quot;rsname&quot;: &quot;Document Resource&quot;\r\n        \/\/\/      }\r\n        \/\/\/    ]\r\n        \/\/\/  }\r\n        \/\/\/ \r\n        \/\/\/ \r\n        \/\/\/ &lt;\/summary&gt;\r\n        public bool HasPermission(string rptToken, string resourceName, string scope)\r\n        {\r\n            try\r\n            {\r\n                var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();\r\n                var jwt = jwtSecurityTokenHandler.ReadJwtToken(rptToken);\r\n\r\n                var authorizationClaim = jwt.Claims.FirstOrDefault(c =&gt; c.Type == &quot;authorization&quot;)?.Value;\r\n\r\n                if (authorizationClaim is null) return false;\r\n\r\n                var authData = JsonSerializer.Deserialize&lt;AuthorizationClaim&gt;(authorizationClaim);\r\n\r\n                return authData?.Permissions?.Any(p =&gt; p.ResourceName == resourceName &amp;&amp; (p.Scopes?.Contains(scope) ?? false)) ?? false;\r\n            }\r\n            catch (Exception)\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n\r\n\r\n    public record AuthorizationClaim(\r\n        &#x5B;property: JsonPropertyName(&quot;permissions&quot;)] List&lt;PermissionClaim&gt;? Permissions\r\n    );\r\n\r\n    public record PermissionClaim(\r\n        &#x5B;property: JsonPropertyName(&quot;rsid&quot;)] string? ResourceId,\r\n        &#x5B;property: JsonPropertyName(&quot;rsname&quot;)] string? ResourceName,\r\n        &#x5B;property: JsonPropertyName(&quot;scopes&quot;)] List&lt;string&gt;? Scopes\r\n    );\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 12<\/strong> <em style=\"color:green;\">(UMA Middleware Geli\u015ftirme)<\/em><br \/>\n\u015eimdi de her iste\u011fi yakalay\u0131p baz\u0131 durumlar\u0131 kontrol edecek \u00e7al\u0131\u015fmalar ger\u00e7ekle\u015ftirmemiz gerekmektedir&#8230; \u015e\u00f6yle ki, gelen istekteki token; normal access token ise permission ticket \u00fcretecek ve 401 d\u00f6nd\u00fcrece\u011fiz, yok e\u011fer RPT ise i\u00e7indeki permission&#8217;lar\u0131 do\u011frulayacak ve duruma g\u00f6re eri\u015fime izin verece\u011fiz. \u0130\u015fte bunun i\u00e7in a\u015fa\u011f\u0131daki gibi bir middleware olu\u015fturmam\u0131z tam yerinde olacakt\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UmaMiddleware(UmaTokenService umaTokenService, RptValidator rptValidator) : IMiddleware\r\n    {\r\n        public async Task InvokeAsync(HttpContext context, RequestDelegate next)\r\n        {\r\n            var path = context.Request.Path.Value ?? &quot;&quot;;\r\n\r\n            \/\/UMA korumas\u0131 alt\u0131ndaki path'leri belirliyoruz. \u00d6rne\u011fin \/documents\/{id} path'i i\u00e7in id'yi al\u0131p o kayna\u011fa eri\u015fim izni olup olmad\u0131\u011f\u0131n\u0131 kontrol edece\u011fiz.\r\n            if (!path.StartsWith(&quot;\/api\/documents&quot;, StringComparison.OrdinalIgnoreCase))\r\n            {\r\n                await next(context);\r\n                return;\r\n            }\r\n\r\n            var authorization = context.Request.Headers.Authorization.ToString();\r\n\r\n            if (string.IsNullOrEmpty(authorization) || !authorization.StartsWith(&quot;Bearer &quot;))\r\n            {\r\n                \/\/Token yok \u2192 UMA ak\u0131\u015f\u0131n\u0131 ba\u015flat\r\n                await ReturnPermissionTicket(context, &quot;Document Resource&quot;, &quot;read&quot;);\r\n                return;\r\n            }\r\n\r\n            var token = authorization&#x5B;&quot;Bearer &quot;.Length..];\r\n\r\n            \/\/Token RPT mi kontrol ediyoruz... (authorization code i\u00e7eriyor mu kontrol ediyoruz)\r\n            var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();\r\n            var jwt = jwtSecurityTokenHandler.ReadJwtToken(token);\r\n            if (jwt.Claims.Any(c =&gt; c.Type == &quot;authorization&quot;))\r\n            {\r\n                var requiredScope = GetScopeForMethod(context.Request.Method);\r\n\r\n                if (rptValidator.HasPermission(token, &quot;Document Resource&quot;, requiredScope))\r\n                    await next(context);\r\n                else\r\n                {\r\n                    context.Response.StatusCode = (int)HttpStatusCode.Forbidden;\r\n                    await context.Response.WriteAsync(&quot;Bu kaynak i\u00e7in yetkiniz bulunmamaktad\u0131r!&quot;);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                \/\/Normal access token ise permission ticket \u00fcretiyor ve 401 d\u00f6n\u00fcyoruz. Client bu ticket'\u0131 al\u0131p Keycloak'tan RPT edinir ve tekrar istekte bulunur.\r\n                await ReturnPermissionTicket(context, &quot;Document Resource&quot;, GetScopeForMethod(context.Request.Method));\r\n            }\r\n\r\n            string GetScopeForMethod(string method) =&gt; method switch\r\n            {\r\n                &quot;GET&quot; =&gt; &quot;read&quot;,\r\n                &quot;POST&quot; =&gt; &quot;write&quot;,\r\n                &quot;PUT&quot; =&gt; &quot;write&quot;,\r\n                &quot;DELETE&quot; =&gt; &quot;delete&quot;,\r\n                _ =&gt; &quot;read&quot;\r\n            };\r\n        }\r\n\r\n        async Task ReturnPermissionTicket(HttpContext context, string resourceId, string scope)\r\n        {\r\n            var ticket = await umaTokenService.GetPermissionTicketAsync(resourceId, scope);\r\n\r\n            if (ticket is null)\r\n            {\r\n                context.Response.StatusCode = 500;\r\n                return;\r\n            }\r\n\r\n            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;\r\n\r\n            \/\/WWW-Authenticate header'\u0131nda UMA realm, as_uri ve ticket bilgilerini client'a g\u00f6nderiyoruz. Client bu bilgileri kullanarak Keycloak'tan RPT alacak.\r\n            \/\/Bu bir UMA standard\u0131d\u0131r ve client'lar\u0131n 401 response ald\u0131klar\u0131nda ne yapmalar\u0131 gerekti\u011fini anlamalar\u0131n\u0131 sa\u011flar.\r\n            context.Response.Headers&#x5B;HeaderNames.WWWAuthenticate] = $&quot;&quot;&quot; UMA realm=&quot;master&quot;, as_uri=&quot;http:\/\/localhost:8080\/realms\/master&quot;, ticket=&quot;{ticket}&quot; &quot;&quot;&quot;;\r\n\r\n            await context.Response.WriteAsJsonAsync(new\r\n            {\r\n                error = &quot;uma_redirect&quot;,\r\n                message = &quot;Permission ticket al\u0131nd\u0131. Bu ticket ile RPT edinin!&quot;,\r\n                ticket = ticket,\r\n                token_endpoint = &quot;http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token&quot;\r\n            });\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Burada dikkat ederseniz gelen istekteki token 14. sat\u0131rda elde edildikten sonra gerekli kontroller sa\u011flanmaktad\u0131r. Sizlere ilgin\u00e7 gelebilecek olan 16 ile 21. sat\u0131r aral\u0131\u011f\u0131ndaki, token&#8217;\u0131n olmama durumuna istinaden ba\u015flat\u0131lan UMA ak\u0131\u015f\u0131d\u0131r. \u015eimdi burada <strong><em>la madem token yok neden iste\u011fi reddetmiyoruz!<\/em><\/strong> diye soruyor olabilirsiniz. Ancak hat\u0131rlaman\u0131z\u0131 istiyorum ki UMA&#8217;n\u0131n felsefesi iste\u011fi reddetmeden \u00f6nce kullan\u0131c\u0131ya nas\u0131l eri\u015febilece\u011fini s\u00f6ylemesinden ge\u00e7mektedir. Yani burada OAuth 2.0 tarz\u0131, token yoksa e\u011fer 401 status code&#8217;u ile istek reddedilsin \u015feklinde bir mant\u0131ktan ziyade; UMA tarz\u0131, token olmasa dahi 401 status code&#8217;unda permission ticket ile client&#8217;a d\u00f6n\u00fc\u015f yap\u0131ls\u0131n ve bu ticket ile Keycloak&#8217;tan RPT al\u0131nmas\u0131 sa\u011flans\u0131n mant\u0131\u011f\u0131nda bir \u00e7al\u0131\u015fma s\u00f6z konusudur. Ha tabi siz yine de token&#8217;\u0131n olmad\u0131\u011f\u0131 bir duruma kar\u015f\u0131n isterseniz direkt iste\u011fi reddedebilirsiniz&#8230;<\/p>\n<p>26 ile 39. sat\u0131r aral\u0131\u011f\u0131na g\u00f6z atarsan\u0131z e\u011fer i\u00e7erisinde &#8216;authorization&#8217; claim&#8217;i sorgulanarak mevcut token&#8217;\u0131n RPT olup olmad\u0131\u011f\u0131 kontrol edilmektedir. E\u011fer RPT ise gelen iste\u011fin mahiyetine g\u00f6re (GET, POST vs.) uygun scope belirlenip (<code>GetScopeForMethod<\/code>), \u00f6nceki sat\u0131rlarda olu\u015fturdu\u011fumuz <em>Document Resource<\/em>&#8216;a dair b\u00f6yle bir aksiyonun olup olmad\u0131\u011f\u0131 <code>RptValidator<\/code> arac\u0131l\u0131\u011f\u0131yla de\u011ferlendirilmektedir. Yok e\u011fer ilgili token, normal bir access token ise 43. sat\u0131rda <code>ReturnPermissionTicket<\/code> metodu arac\u0131l\u0131\u011f\u0131yla ilgili resource&#8217;a uygun scope i\u00e7in permission ticket talep edilmektedir.<\/p>\n<p>T\u00fcm bunlar\u0131n d\u0131\u015f\u0131nda 56 ile 79. sat\u0131r aral\u0131\u011f\u0131nda permission ticket olu\u015fturulmas\u0131n\u0131 sa\u011flayan <code>ReturnPermissionTicket<\/code> metodunun i\u00e7indeki 70. sat\u0131rda bulunan kar\u0131\u015f\u0131k ifadeyi de izah etmemiz gerekirse e\u011fer bu, HTTP standard\u0131ndaki <code>WWW-Authenticate<\/code> header&#8217;\u0131n\u0131n UMA versiyonudur. Bu header ile client&#8217;a, <em>-bu kayna\u011fa eri\u015febilmek i\u00e7in \u015fu \u015fekilde authenticate olmal\u0131s\u0131n-<\/em> denilmektedir. Yani bir ba\u015fka deyi\u015fle client&#8217;a, <em>-git Keycloak&#8217;tan UMA ile yetki al-<\/em> demenin resmi HTTP cevab\u0131 bu \u015fekildedir diyebiliriz&#8230;<\/p>\n<\/li>\n<li><strong>Ad\u0131m 13<\/strong> <em style=\"color:green;\">(<code>\/api\/documents\/{id}<\/code> Endpoint&#8217;ini Geli\u015ftirme)<\/em><br \/>\n\u00d6nceki ad\u0131mlarda olu\u015fturdu\u011fumuz resource&#8217;un URIs&#8217;inde belirtilen path&#8217;e kar\u015f\u0131l\u0131k bir endpoint olu\u015ftural\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/api\/documents\/{id}&quot;, (string id) =&gt;\r\n{\r\n    \/\/Buraya gelindiyse middleware RPT'yi do\u011frulam\u0131\u015f demektir...\r\n    return Results.Ok(new\r\n    {\r\n        id,\r\n        title = &quot;Document&quot;,\r\n        content = &quot;Bu i\u00e7erik UMA 2.0 ile korunmaktad\u0131r.&quot;,\r\n        accessedAt = DateTime.UtcNow\r\n    });\r\n});\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 14<\/strong> <em style=\"color:green;\">(Authenticate&#8217;i Yap\u0131land\u0131rma ve Temel Ayarlar)<\/em><br \/>\n\u015eimdi de temel JWT authentication yap\u0131lanmas\u0131yla birlikte geri kalan gerekli IoC container konfig\u00fcrasyonlar\u0131n\u0131 <em>Program.cs<\/em> dosyas\u0131nda tamamlayal\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\nbuilder.Services.AddHttpClient();\r\nbuilder.Services.AddSingleton&lt;UmaTokenService&gt;();\r\nbuilder.Services.AddSingleton&lt;RptValidator&gt;();\r\nbuilder.Services.AddSingleton&lt;UmaMiddleware&gt;();\r\n\r\nbuilder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)\r\n    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =&gt;\r\n    {\r\n        options.Authority = builder.Configuration&#x5B;&quot;Keycloak:Authority&quot;];\r\n        options.Audience = builder.Configuration&#x5B;&quot;Keycloak:ClientId&quot;];\r\n        options.RequireHttpsMetadata = false;\r\n        options.TokenValidationParameters = new()\r\n        {\r\n            ValidateIssuer = true,\r\n            ValidateAudience = false, \/\/UMA'da audience kontrol\u00fc middleware'da yap\u0131lmaktad\u0131r. Burada sadece token'\u0131n Keycloak taraf\u0131ndan imzalan\u0131p imzalanmad\u0131\u011f\u0131 kontrol edilmektedir.\r\n            ValidateLifetime = true\r\n        };\r\n    });\r\n\r\nvar app = builder.Build();\r\napp.UseAuthentication();\r\n\r\napp.UseMiddleware&lt;UmaMiddleware&gt;();\r\n\r\n.\r\n.\r\n.\r\n\r\napp.Run();\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong>Ad\u0131m 15<\/strong> <em style=\"color:green;\">(Test)<\/em><br \/>\nEvet&#8230; Her \u015fey haz\u0131r&#8230; Art\u0131k testimize ge\u00e7ebiliriz. Bunun i\u00e7in Postman \u00fczerinden kullan\u0131c\u0131 ad\u0131na a\u015fa\u011f\u0131daki istek arac\u0131l\u0131\u011f\u0131yla access token talebinde bulunal\u0131m:<\/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 http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token<br \/>\n<\/strong>\n<\/div>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;\">grant_type:  password<br \/>\nclient_id:   postman-client<br \/>\nusername:    gncy<br \/>\npassword:    123<br \/>\nscope:       openid\n<\/div>\n<p>Ard\u0131ndan bu access token ile Asp.NET Core API uygulamam\u0131z\u0131n, resource&#8217;a uygun \u015fekilde tasarlad\u0131\u011f\u0131m\u0131z endpoint&#8217;ine istekte bulunal\u0131m:<\/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;width:50%;\">\nAuthorization: Bearer ACCESS_TOKEN\n<\/div>\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 https:\/\/localhost:7086\/api\/documents\/123<br \/>\n<\/strong>\n<\/div>\n<p>Bu istek s\u00fcrecinde middleware devreye girecek ve ilgili access token&#8217;\u0131n RPT olmad\u0131\u011f\u0131n\u0131 anlayarak, Keycloak&#8217;tan ilgili kaynak i\u00e7in bir permission ticket isteyecektir. Keycloak, ticket \u00fcretecek ve Asp.NET Core&#8217;da bu ticket&#8217;\u0131 401 status code&#8217;u e\u015fli\u011finde client&#8217;a a\u015fa\u011f\u0131daki gibi geri d\u00f6nd\u00fcrm\u00fc\u015f olacakt\u0131r.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"1404\" height=\"173\" class=\"aligncenter size-full wp-image-28641\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14.png 1404w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14-300x37.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14-1024x126.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-14-768x95.png 768w\" sizes=\"auto, (max-width: 1404px) 100vw, 1404px\" \/><\/a>\u015eimdi bu ticket&#8217;\u0131 al\u0131p, yine Postman arac\u0131l\u0131\u011f\u0131yla (\u00e7\u00fcnk\u00fc hala client&#8217;\u0131m\u0131z o) a\u015fa\u011f\u0131daki adrese yeni bir access token talebinde bulunal\u0131m:<\/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;width:50%;\">\nAuthorization: Bearer ACCESS_TOKEN\n<\/div>\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 http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token<br \/>\n<\/strong>\n<\/div>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;\">grant_type:  urn:ietf:params:oauth:grant-type:uma-ticket<br \/>\nticket:      PERMISSION_TICKET\n<\/div>\n<p>E\u011fer ki bu istek neticesinde a\u015fa\u011f\u0131daki <code>access_denied<\/code> hatas\u0131n\u0131 al\u0131yorsan\u0131z, bilin ki politikaya uymayan bir durum s\u00f6z konusudur.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-15.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-15.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"348\" height=\"81\" class=\"aligncenter size-full wp-image-28642\" \/><\/a><strong>Ne olabilir?<\/strong> sorusuna kar\u015f\u0131n ilk kontrol edece\u011finiz yer ilgili resource&#8217;un politikalar\u0131 olmal\u0131d\u0131r. Hat\u0131rlarsan\u0131z e\u011fer bizler <em>&#8216;Document Read Permission&#8217;<\/em> ad\u0131n\u0131 verdi\u011fimiz permission&#8217;da <em>&#8216;Has User Role&#8217;<\/em> politikas\u0131n\u0131 uygulam\u0131\u015ft\u0131k. Haliyle bu politika gere\u011fi ilgili kullan\u0131c\u0131n\u0131n &#8216;user&#8217; rol\u00fcne sahip olmas\u0131 gerekmektedir. E\u011fer bu hatay\u0131 al\u0131yorsan\u0131z muhtemelen test i\u015fleminde kulland\u0131\u011f\u0131n\u0131z user&#8217;da ilgili rol\u00fcn atanmad\u0131\u011f\u0131n\u0131 s\u00f6yleyebiliriz.<\/p>\n<p>E\u011fer her \u015fey yolundaysa, permission ticket ile talep edilen \u00f6zel yetkilendirilmi\u015f access token (RPT) a\u015fa\u011f\u0131daki gibi elde edilecektir:<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-16.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-16.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"580\" height=\"794\" class=\"aligncenter size-full wp-image-28644\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-16.png 580w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-16-219x300.png 219w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a>Bu a\u015famadan sonra tek yap\u0131lmas\u0131 gereken RPT access token&#8217;\u0131 arac\u0131l\u0131\u011f\u0131yla tekrar Asp.NET Core uygulamas\u0131ndaki endpoint&#8217;e istekte bulunmakt\u0131r!<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-17.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-17.png\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"430\" height=\"190\" class=\"aligncenter size-full wp-image-28645\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-17.png 430w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-17-300x133.png 300w\" sizes=\"auto, (max-width: 430px) 100vw, 430px\" \/><\/a>\u0130\u015fte bu kadar&#8230; \ud83d\ude42\n<\/li>\n<\/ul>\n<h5><span class=\"ez-toc-section\" id=\"UMAyi_Custom_Authorization_Requirement_Handler_Yoluyla_Uygulama_En_Dogru_Yol\"><\/span>UMA&#8217;y\u0131 Custom Authorization Requirement + Handler Yoluyla Uygulama (En Do\u011fru Yol)<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Yukar\u0131daki \u00e7al\u0131\u015fmada UMA&#8217;y\u0131 uygularken permission&#8217;daki scope kontrol\u00fcn\u00fc de manuel bir \u015fekilde sa\u011flamaktay\u0131z. Halbuki ideal olan bunu Asp.NET Core&#8217;un native yetkilendirme pipeline&#8217;\u0131na yans\u0131tabilmek ve orada bir policy mant\u0131\u011f\u0131nda ger\u00e7ekle\u015ftirebilmektir.<\/p>\n<p>Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi custom bir authorization requirement olu\u015fturarak s\u00fcreci daha efektif hale getirebiliriz:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public record UmaPermissionRequirement(string ResourceName, string Scope) : IAuthorizationRequirement;\r\n<\/pre>\n<\/div>\n<p>Devam\u0131nda ise bu requirement&#8217;\u0131 a\u015fa\u011f\u0131daki handler ile do\u011frulayabilir ve RPT kontrol\u00fcn\u00fc sa\u011flayabiliriz:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UmaPermissionHandler(RptValidator rptValidator) : AuthorizationHandler&lt;UmaPermissionRequirement&gt;\r\n    {\r\n        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UmaPermissionRequirement requirement)\r\n        {\r\n            if (context.Resource is not HttpContext httpContext)\r\n            {\r\n                context.Fail();\r\n                return Task.CompletedTask;\r\n            }\r\n\r\n            var authorizationHeader = httpContext.Request.Headers.Authorization.ToString();\r\n\r\n            \/\/Hi\u00e7 token yoksa ba\u015far\u0131s\u0131z authorization'\u0131n detaylar\u0131yla birlikte Fail'liyoruz\r\n            if (string.IsNullOrEmpty(authorizationHeader) || !authorizationHeader.StartsWith(&quot;Bearer &quot;))\r\n            {\r\n                context.Fail(new AuthorizationFailureReason(this, &quot;no_token&quot;));\r\n                return Task.CompletedTask;\r\n            }\r\n\r\n            var token = httpContext.Request.Headers.Authorization.ToString().Replace(&quot;Bearer &quot;, &quot;&quot;);\r\n\r\n            \/\/E\u011fer token varsa RPT'mi de\u011fil mi kontrol ediyoruz\r\n            var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();\r\n            var jwt = jwtSecurityTokenHandler.ReadJwtToken(token);\r\n            if (!jwt.Claims.Any(c =&gt; c.Type == &quot;authorization&quot;))\r\n            {\r\n                context.Fail(new AuthorizationFailureReason(this, &quot;not_rpt&quot;));\r\n                return Task.CompletedTask;\r\n            }\r\n\r\n            \/\/RPT ise permission'lar\u0131 kontrol ediyoruz.\r\n            if (rptValidator.HasPermission(token, requirement.ResourceName, requirement.Scope))\r\n                context.Succeed(requirement);\r\n            else\r\n                context.Fail();\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Devam\u0131nda ise authorization&#8217;\u0131n yaln\u0131zca ba\u015far\u0131s\u0131z oldu\u011fu durumlarda i\u015flem yapacak olan a\u015fa\u011f\u0131daki gibi bir middleware ile de gerekli kontrolleri sa\u011flayabilir ve fail sebebi <code>no_token<\/code> yahut <code>not_rpt<\/code> ise permission ticket alabilir yahut <code>permission_denied<\/code> ise de 403 d\u00f6nd\u00fcrebiliriz:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UmaAuthorizationMiddlewareResultHandler(UmaTokenService umaTokenService) : IAuthorizationMiddlewareResultHandler\r\n    {\r\n        private readonly AuthorizationMiddlewareResultHandler _default = new();\r\n        public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)\r\n        {\r\n            \/\/Authorization ba\u015far\u0131l\u0131ysa direkt ge\u00e7iriyoruz\r\n            if (authorizeResult.Succeeded)\r\n            {\r\n                await next(context);\r\n                return;\r\n            }\r\n\r\n            \/\/Hatal\u0131ysa nedenine bak\u0131yoruz\r\n            var reason = authorizeResult.AuthorizationFailure?.FailureReasons.FirstOrDefault()?.Message;\r\n\r\n            \/\/RPT varsa ama yetersiz permission'sa \u2192 403\r\n            if (reason == &quot;permission_denied&quot;)\r\n            {\r\n                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;\r\n                await context.Response.WriteAsJsonAsync(new\r\n                {\r\n                    error = &quot;forbidden&quot;,\r\n                    message = &quot;Bu resource i\u00e7in yetkiniz bulunmamaktad\u0131r.&quot;\r\n                });\r\n                return;\r\n            }\r\n\r\n            \/\/Token yoksa ya da RPT de\u011filse \u2192 401\r\n            if (reason is &quot;no_token&quot; or &quot;not_rpt&quot;)\r\n            {\r\n                \/\/Hangi endpoint i\u00e7in ticket isteniyorsa bunu requirement'tan almak i\u00e7in policy'e bak\u0131yoruz\r\n                var requirement = policy.Requirements.OfType&lt;UmaPermissionRequirement&gt;().FirstOrDefault();\r\n\r\n                if (requirement == null)\r\n                {\r\n                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;\r\n                    return;\r\n                }\r\n\r\n                var ticket = await umaTokenService.GetPermissionTicketAsync(requirement.ResourceName, requirement.Scope);\r\n\r\n                if (ticket == null)\r\n                {\r\n                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;\r\n                    return;\r\n                }\r\n\r\n                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;\r\n                context.Response.Headers&#x5B;HeaderNames.WWWAuthenticate] = $&quot;&quot;&quot; UMA realm=&quot;master&quot;, as_uri=&quot;http:\/\/localhost:8080\/realms\/master&quot;, ticket=&quot;{ticket}&quot; &quot;&quot;&quot;;\r\n\r\n                await context.Response.WriteAsJsonAsync(new\r\n                {\r\n                    error = &quot;uma_redirect&quot;,\r\n                    message = &quot;Permission ticket al\u0131nd\u0131. Bu ticket ile RPT edinin!&quot;,\r\n                    ticket = ticket,\r\n                    token_endpoint = &quot;http:\/\/localhost:8080\/realms\/master\/protocol\/openid-connect\/token&quot;\r\n                });\r\n            }\r\n\r\n            \/\/Token s\u00fcresi dolmas\u0131 vs. gibi di\u011fer durumlar i\u00e7in default davran\u0131\u015f\u0131 devreye al\u0131yoruz\r\n            await _default.HandleAsync(next, context, policy, authorizeResult);\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>T\u00fcm bu i\u015flemlerden sonra tek yap\u0131lmas\u0131 gereken a\u015fa\u011f\u0131daki gibi pipeline&#8217;a uygun bir \u015fekilde scope&#8217;lar \u00fczerinden politikalar\u0131n olu\u015fturulmas\u0131 ve endpoint&#8217;te kullan\u0131lmas\u0131d\u0131r&#8230;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddAuthorization(options =&gt;\r\n{\r\n    options.AddPolicy(&quot;document:read&quot;, policy =&gt;\r\n        policy.Requirements.Add(new UmaPermissionRequirement(&quot;Document Resource&quot;, &quot;read&quot;)));\r\n\r\n    options.AddPolicy(&quot;document:write&quot;, policy =&gt;\r\n        policy.Requirements.Add(new UmaPermissionRequirement(&quot;Document Resource&quot;, &quot;write&quot;)));\r\n});\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/api\/documents\/{id}&quot;, (string id) =&gt;\r\n{\r\n    \/\/Buraya gelindiyse middleware RPT'yi do\u011frulam\u0131\u015f demektir...\r\n    return Results.Ok(new\r\n    {\r\n        id,\r\n        title = &quot;Document&quot;,\r\n        content = &quot;Bu i\u00e7erik UMA 2.0 ile korunmaktad\u0131r.&quot;,\r\n        accessedAt = DateTime.UtcNow\r\n    });\r\n}).RequireAuthorization(policyNames: &quot;document:read&quot;);\r\n<\/pre>\n<\/div>\n<p>\u0130\u015fte bu kadar basit&#8230;<div id=\"attachment_28649\" style=\"width: 694px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-28649\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.jpg\" alt=\"Keycloak&#039;da Advanced Authorization Services (UMA 2.0) Sistemini \u0130nceleyelim... #12\" width=\"684\" height=\"492\" class=\"size-full wp-image-28649\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12.jpg 684w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/04\/Keycloakda-Advanced-Authorization-Services-UMA-2.0-Sistemini-Inceleyelim.-12-300x216.jpg 300w\" sizes=\"auto, (max-width: 684px) 100vw, 684px\" \/><\/a><p id=\"caption-attachment-28649\" class=\"wp-caption-text\">UMA 2.0 ak\u0131\u015f\u0131n\u0131n ve RPT&#8217;nin davran\u0131\u015fsal olarak g\u00f6rsel \u00f6zeti&#8230;<\/p><\/div>Tabi burada, uygulama zemininde dikkat etmenizde fayda g\u00f6rece\u011fim baz\u0131 tecr\u00fcbevi noktalar mevcuttur. Bunlar\u0131 sizler ya\u015fad\u0131k\u00e7a anlayacak ve sindirecek olsan\u0131z da yine hafiften \u00f6nden vurgulamakta fayda g\u00f6r\u00fcyorum&#8230;<\/p>\n<p>UMA 2.0 senaryolar\u0131nda, RPT al\u0131m s\u00fcrecinde <code>access_denied<\/code> hatas\u0131 y\u00fcksek olas\u0131d\u0131r. Burada ilk bakaca\u011f\u0131n\u0131z nokta her daim permission&#8217;\u0131n policy&#8217;lerinin do\u011frulan\u0131p do\u011frulanmad\u0131\u011f\u0131 olmal\u0131d\u0131r. Ayr\u0131ca 401 d\u00f6ng\u00fcs\u00fc de bazen ka\u00e7\u0131n\u0131lmaz olabilmektedir. Burada da kontrol edilen access token i\u00e7erisinde &#8216;authorization&#8217; claim&#8217;i var m\u0131 yok mu taraf\u0131n\u0131zca manuel kontrol edilmelidir. Ha ayr\u0131ca client&#8217;\u0131n authorization ayarlar\u0131nda &#8216;Remote resource management&#8217; yap\u0131land\u0131rmas\u0131n\u0131 aktifle\u015ftirme de unutulmamal\u0131d\u0131r. Bunlara dikkat edildi\u011fi s\u00fcrece di\u011fer ya\u015fanacak hatalar art\u0131k y\u00fcksek ihtimal UMA&#8217;n\u0131n d\u0131\u015f\u0131nda ba\u015fka nedenlere dayanmaktad\u0131r \ud83d\ude42<\/p>\n<p>Evet, g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere UMA 2.0 gibi kompleks ve hassas yap\u0131land\u0131rma gerektiren bir ak\u0131\u015f\u0131 a&#8217;dan z&#8217;ye tam teferruatl\u0131 teorik bir inceleme e\u015fli\u011finde, pratikte de ele alm\u0131\u015f ve siz de\u011ferli okuyucular\u0131m\u0131zla birlikte deneyimlemi\u015f bulunuyoruz.<\/p>\n<p>Nihai olarak;<br \/>\n\u0130\u00e7erik boyunca, klasik rol bazl\u0131 yetkilendirmenin \u00f6tesine ge\u00e7erek UMA 2.0 standard\u0131n\u0131 temel alan Keycloak Advanced Authorization Services&#8217;i teorik ve pratik boyutlar\u0131yla ele alm\u0131\u015f bulunuyoruz. Resource, scope, policy ve permission kavramlar\u0131n\u0131n bir araya geldi\u011fi ve dinamik izin ak\u0131\u015flar\u0131 ile birlikte hassas eri\u015fim kontrolleri gerektiren senaryolarda sundu\u011fu esneklikle \u00f6ne \u00e7\u0131kan bu ak\u0131\u015f\u0131, Asp.NET Core entegrasyonu \u00fczerinden ad\u0131m ad\u0131m, permission ticket ve RPT mekanizmalar\u0131n\u0131n pratikte nas\u0131l i\u015fledi\u011fini deneyimleyerek g\u00f6zler \u00f6n\u00fcne sermi\u015f bulunuyoruz.<\/p>\n<p>Unutulmamal\u0131d\u0131r ki, UMA 2.0 her senaryo i\u00e7in uygun de\u011fildir! Basit yetkilendirme ihtiya\u00e7lar\u0131nda gereksiz karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilece\u011fi gibi, do\u011fru kullan\u0131ld\u0131\u011f\u0131nda ise merkezi ve dinamik bir yetki y\u00f6netimi imkan\u0131 sunmaktad\u0131r.<\/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;\">\u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki GitHub reposundan eri\u015febilirsiniz.<\/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 konuya dair \u00f6rnek \u00e7al\u0131\u015fman\u0131n kaynak kodlar\u0131n\u0131 ve mimari yap\u0131s\u0131n\u0131 i\u00e7ermektedir. Detaylar i\u00e7in GitHub \u00fczerinden incelemede bulunabilirsiniz.\n  <\/div>\n<p>  <a href=\"https:\/\/github.com\/gncyyldz\/Keycloak.Examples\/tree\/Keycloak8.Keycloakda-Advanced-Authorization-Services-UMA-Sistemini-%C4%B0nceleyelim\" 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, UMA 2.0 standard\u0131n\u0131 temel alan; klasik rol bazl\u0131 yetkilendirme mant\u0131\u011f\u0131ndan \u00e7ok daha g\u00fc\u00e7l\u00fc bir yap\u0131 sunan policy (kural) tabanl\u0131 eri\u015fim kontrol sistemi olan Advanced Authorization Services sistemini teorik olarak ele alacak&#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":[5701,5699,3145,3055,5710,5706,5705,3054,5707,5711,5709,5703,3835,3146,5708,5715,5713,5702,5714,5700,5712,5704],"class_list":["post-28592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-keycloak","tag-advanced-authorization","tag-advanced-authorization-services","tag-authorization-server","tag-iauthorizationrequirement","tag-pat","tag-permission-explosion","tag-permission-ticket","tag-policy-based-authorization","tag-policy-tabanli-yetkilendirme","tag-protection-api-token","tag-rba","tag-requesting-party-token","tag-resource-owner","tag-resource-server","tag-resource-based-authorization","tag-resource-based-permission","tag-role-based-policy","tag-rpt","tag-scope-based-permission","tag-uma-2-0","tag-user-based-policy","tag-user-managed-access-2-0"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28592","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=28592"}],"version-history":[{"count":33,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28592\/revisions"}],"predecessor-version":[{"id":28650,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28592\/revisions\/28650"}],"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=28592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=28592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=28592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}