﻿
{"id":19070,"date":"2020-11-15T23:13:21","date_gmt":"2020-11-15T23:13:21","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=19070"},"modified":"2020-11-15T23:15:20","modified_gmt":"2020-11-15T23:15:20","slug":"identityserver4-yazi-serisi-16-merkezi-uyelik-sistemi-ozel-identity-resource-ekleme","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/identityserver4-yazi-serisi-16-merkezi-uyelik-sistemi-ozel-identity-resource-ekleme\/","title":{"rendered":"IdentityServer4 Yaz\u0131 Serisi #16 &#8211; Merkezi \u00dcyelik Sistemi &#8211; \u00d6zel Identity Resource Ekleme"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/identityserver4-yazi-serisi\/\" rel=\"noopener noreferrer\" target=\"_blank\">IdentityServer4 Yaz\u0131 Serisi<\/a>nin onbirinci makalesi olan <a href=\"https:\/\/www.gencayyildiz.com\/blog\/identityserver4-yazi-serisi-11-merkezi-uyelik-sistemi-temelleri\/\" rel=\"noopener noreferrer\" target=\"_blank\">Merkezi \u00dcyelik Sistemi Temelleri<\/a> ba\u015fl\u0131kl\u0131 i\u00e7eri\u011fimizin 5. ad\u0131m\u0131nda Identity Resource \u00fczerine odaklanm\u0131\u015ft\u0131k ve \u00f6ntan\u0131ml\u0131 olan &#8216;OpenId&#8217; ve &#8216;Profile&#8217; bilgilerini ekleyerek kullan\u0131c\u0131 id\/subject id de\u011feriyle birlikte kullan\u0131c\u0131 profil bilgilerini tan\u0131mlam\u0131\u015ft\u0131k. Bu i\u00e7eri\u011fimizde ise bu \u00f6ntan\u0131ml\u0131 identity resource&#8217;lerin d\u0131\u015f\u0131nda custom(\u00f6zel) identity resource tan\u0131mlamay\u0131 ele alacak ve bunu client taraf\u0131ndan talep etmeyi inceleyece\u011fiz.<\/p>\n<p>IdentityServer4 uygulamas\u0131na custom identity resource ekleyebilmek i\u00e7in a\u015fa\u011f\u0131daki ad\u0131mlar\u0131n s\u0131ras\u0131yla uygulanmas\u0131 gerekmektedir.<\/p>\n<ul>\n<li><strong>Ad\u0131m 1<\/strong><br \/>\n&#8216;AuthServer&#8217; uygulamas\u0131ndaki &#8216;Config.cs&#8217; dosyas\u0131nda identity resource&#8217;lerin tan\u0131mland\u0131\u011f\u0131 &#8216;GetIdentityResources&#8217; metoduna a\u015fa\u011f\u0131daki gibi custom de\u011fer(ler) olu\u015fturulmal\u0131d\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static IEnumerable&lt;IdentityResource&gt; GetIdentityResources()\r\n        {\r\n            return new List&lt;IdentityResource&gt;\r\n            {\r\n                new IdentityResources.OpenId(),\r\n                new IdentityResources.Profile(),\r\n                new IdentityResource {\r\n                    Name = &quot;PositionAndAuthority&quot;,\r\n                    DisplayName = &quot;Position And Authority&quot;,\r\n                    Description = &quot;Kullan\u0131c\u0131 pozisyonu ve yetkisi.&quot;,\r\n                    UserClaims = { &quot;position&quot;, &quot;authority&quot; }\r\n                }\r\n            };\r\n        }\r\n<\/pre>\n<p>Burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere &#8216;PositionAndAuthority&#8217; isminde bir identity resource olu\u015fturulmu\u015ftur ve i\u00e7erisinde &#8216;position&#8217; ve &#8216;authority&#8217; claim&#8217;leri mevcuttur.\n<\/li>\n<li><strong>Ad\u0131m 2<\/strong><br \/>\nYukar\u0131da olu\u015fturulan identity resource claim&#8217;lerini kullan\u0131c\u0131lar i\u00e7inde claim olarak tan\u0131mlamam\u0131z gerekmektedir. Bunun i\u00e7in yine &#8216;Config.cs&#8217; dosyas\u0131ndaki &#8216;GetTestUsers&#8217; metodundaki ilgili kullan\u0131c\u0131lara a\u015fa\u011f\u0131daki gibi eklemede bulunmak gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static IEnumerable&lt;TestUser&gt; GetTestUsers()\r\n        {\r\n            return new List&lt;TestUser&gt; {\r\n                new TestUser {\r\n                    .\r\n                    .\r\n                    .\r\n                    Claims = {\r\n                        new Claim(&quot;name&quot;,&quot;test user1&quot;),\r\n                        new Claim(&quot;given_name&quot;,&quot;test user1 given&quot;),\r\n                        new Claim(&quot;website&quot;,&quot;https:\/\/wwww.testuser1.com&quot;),\r\n                        new Claim(&quot;gender&quot;,&quot;1&quot;),\r\n                        new Claim(&quot;position&quot; , &quot;Test Kullan\u0131c\u0131s\u0131 1&quot;),\r\n                        new Claim(&quot;authority&quot;, &quot;Test 1&quot;)\r\n                    }\r\n                },\r\n                new TestUser {\r\n                    .\r\n                    .\r\n                    .\r\n                    Claims = {\r\n                        new Claim(&quot;name&quot;,&quot;test user2&quot;),\r\n                        new Claim(&quot;website&quot;,&quot;https:\/\/wwww.testuser2.com&quot;),\r\n                        new Claim(&quot;gender&quot;,&quot;0&quot;),\r\n                        new Claim(&quot;position&quot; , &quot;Test Kullan\u0131c\u0131s\u0131 2&quot;),\r\n                        new Claim(&quot;authority&quot;, &quot;Test 2&quot;)\r\n                    }\r\n                }\r\n            };\r\n        }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere identity resource&#8217;da olu\u015fturulan &#8216;position&#8217; ve &#8216;authority&#8217; claim&#8217;lerine kar\u015f\u0131l\u0131k de\u011ferler verilmi\u015ftir. Tabi burada kafa kar\u0131\u015ft\u0131rabilecek bir durum vard\u0131r. O da \u00f6nceki makalelerde kullan\u0131c\u0131lara tan\u0131mlad\u0131\u011f\u0131m\u0131z &#8216;website&#8217;, &#8216;gender&#8217; vs. gibi claim bilgileridir. Do\u011frusu bu bilgileri \u00f6nceden tan\u0131mland\u0131\u011f\u0131 i\u00e7in kald\u0131rmaya gerek duymad\u0131m. \u0130lgili claim&#8217;lere dair 1. ad\u0131mda oldu\u011fu gibi identity resource&#8217;ler olu\u015fturup uygulamada client&#8217;\u0131n talep edebilece\u011fi hale getirebilirsiniz.\n<\/li>\n<li><strong>Ad\u0131m 3<\/strong><br \/>\n\u0130lgili claim&#8217;leri kullan\u0131c\u0131lar i\u00e7inde tan\u0131mlad\u0131ktan sonra client&#8217;ta bu identity resource&#8217;\u00fcn &#8216;AllowedScopes&#8217; property&#8217;si ile talep edilmesi gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static IEnumerable&lt;Client&gt; GetClients()\r\n        {\r\n            return new List&lt;Client&gt;\r\n            {\r\n                new Client\r\n                        {\r\n                            ClientId = &quot;GarantiBankasi&quot;,\r\n                            .\r\n                            .\r\n                            .\r\n                            AllowedScopes = { &quot;Garanti.Write&quot;, &quot;Garanti.Read&quot; }\r\n                        },\r\n                new Client\r\n                        {\r\n                            ClientId = &quot;HalkBankasi&quot;,\r\n                            .\r\n                            .\r\n                            .\r\n                            AllowedScopes = { &quot;HalkBank.Write&quot;, &quot;HalkBank.Read&quot; }\r\n                        },\r\n                new Client\r\n                        {\r\n                            ClientId = &quot;OnlineBankamatik&quot;,\r\n                            .\r\n                            .\r\n                            .\r\n                            AllowedScopes = {\r\n                                IdentityServerConstants.StandardScopes.OpenId,\r\n                                IdentityServerConstants.StandardScopes.Profile,\r\n                                IdentityServerConstants.StandardScopes.OfflineAccess,\r\n                                &quot;Garanti.Write&quot;,\r\n                                &quot;Garanti.Read&quot;,\r\n                                &quot;PositionAndAuthority&quot;\r\n                                            },\r\n                            .\r\n                            .\r\n                            .\r\n                        }\r\n            };\r\n        }\r\n<\/pre>\n<p>33. sat\u0131ra g\u00f6z atarsan\u0131z e\u011fer ilgili identity resource client taraf\u0131ndan scope olarak talep edilmektedir.\n<\/li>\n<li><strong>Ad\u0131m 4<\/strong><br \/>\nAyriyetten ilgili identity resource de\u011ferlerinin client uygulamas\u0131n\u0131n &#8216;Startup.cs&#8217; dosyas\u0131ndan da scope olarak talep edilmesi gerekmektedir. Bunun i\u00e7in;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddAuthentication(_ =&gt;\r\n            {\r\n                _.DefaultScheme = &quot;OnlineBankamatikCookie&quot;;\r\n                _.DefaultChallengeScheme = &quot;oidc&quot;;\r\n            })\r\n            .AddCookie(&quot;OnlineBankamatikCookie&quot;)\r\n            .AddOpenIdConnect(&quot;oidc&quot;, _ =&gt;\r\n            {\r\n                .\r\n                .\r\n                .\r\n                _.Scope.Add(&quot;offline_access&quot;);\r\n                _.Scope.Add(&quot;Garanti.Write&quot;);\r\n                _.Scope.Add(&quot;Garanti.Read&quot;);\r\n                _.Scope.Add(&quot;PositionAndAuthority&quot;);\r\n            });\r\n            services.AddControllersWithViews();\r\n        }\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>19. sat\u0131rda oldu\u011fu gibi &#8216;Scope.Add&#8217; komutuyla talebin eklenmesi yeterlidir.\n<\/li>\n<li><strong>Ad\u0131m 5<\/strong><br \/>\nBu ad\u0131ma kadar yap\u0131lan konfig\u00fcrasyon ile client&#8217;\u0131n kullan\u0131c\u0131ya dair &#8216;PositionAndAuthority&#8217; name de\u011ferine sahip identity resource&#8217;u talep etmesi neticesinde ilgili claim de\u011ferlerini elde edebilece\u011fi bildirilmi\u015ftir. Lakin \u00fcretilecek JWT&#8217;de bu de\u011ferlerin hangi claim&#8217;ler ile e\u015fle\u015fece\u011fi bildirilmemi\u015ftir. <strong><em>Hoca! Zaten &#8216;Profile&#8217; ve &#8216;OpenId&#8217; identity resource&#8217;lerinde bildirmedik, \u00f6zel olu\u015fturdu\u011fumuzu niye bildirelim!<\/em><\/strong> \u015feklinde sorunuzu duyar gibiyim&#8230; Evet, Profile ve OpenId \u00f6ntan\u0131ml\u0131 identity resource olduklar\u0131ndan dolay\u0131 manuel m\u00fcdahaleye gerek kalmaks\u0131z\u0131n direkt olarak JWT&#8217;de bir claim ile e\u015fle\u015ftirilmektedir. Lakin custom geli\u015ftirilen identity resource&#8217;lar\u0131n JWT&#8217;de hangi claim ile ta\u015f\u0131naca\u011f\u0131 manuel belirtilmelidir. Bunun i\u00e7in yine client&#8217;\u0131n &#8216;Startup.cs&#8217;deki &#8216;AddOpenIdConnect&#8217; servisinde &#8216;<em>Microsoft.AspNetCore.Authentication<\/em>&#8216; namespace&#8217;i alt\u0131ndaki &#8216;MapUniqueJsonKey&#8217; metoduyla a\u015fa\u011f\u0131daki konfig\u00fcrasyonlar ger\u00e7ekle\u015ftirilmelidir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            .\r\n            .\r\n            .AddOpenIdConnect(&quot;oidc&quot;, _ =&gt;\r\n            {\r\n                .\r\n                .\r\n                .\r\n                _.ClaimActions.MapUniqueJsonKey(&quot;position&quot;, &quot;position&quot;);\r\n                _.ClaimActions.MapUniqueJsonKey(&quot;authority&quot;, &quot;authority&quot;);\r\n            });\r\n<\/pre>\n<p>Burada &#8216;MapUniqueJsonKey&#8217; metodunun birinci parametresi claim ad\u0131n\u0131, ikinci parametre ise olu\u015fturulacak JWT&#8217;de ki kar\u015f\u0131l\u0131\u011f\u0131n\u0131 belirlemektedir. Dolay\u0131s\u0131yla &#8216;position&#8217; claim&#8217;i &#8216;position&#8217; json key&#8217;i ile e\u015fle\u015ftirilmekte ve b\u00f6ylece olu\u015fturulacak JWT&#8217;de &#8216;position&#8217; de\u011feri ile ta\u015f\u0131nabilece\u011fi bildirilmektedir. Benzer mant\u0131k &#8216;authority&#8217; claim&#8217;i i\u00e7inde ge\u00e7erlidir.\n<\/li>\n<\/ul>\n<p>Evet, i\u015fte bu kadar \ud83d\ude42<br \/>\n\u015eimdi s\u0131ra sisteme yeni eklenen identity resource&#8217;e kar\u015f\u0131l\u0131k gelen kullan\u0131c\u0131lardaki claim&#8217;lerin, client taraf\u0131ndan yap\u0131lan talep neticesinde elde edilip edilmedi\u011fini test etmeye gelmi\u015ftir.<\/p>\n<h3>Test Edelim<\/h3>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme.gif\" alt=\"IdentityServer4 Yaz\u0131 Serisi #16 - Merkezi \u00dcyelik Sistemi - \u00d6zel Identity Resource Ekleme\" width=\"800\" height=\"667\" class=\"aligncenter size-full wp-image-19093\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere kullan\u0131c\u0131 giri\u015f yapt\u0131ktan sonra bir \u00f6nceki makalemizde konfig\u00fcre etti\u011fimiz onay sayfas\u0131 bizleri kar\u015f\u0131lamakta ve tasarlad\u0131\u011f\u0131m\u0131z &#8216;PositionAndAuthority&#8217; identity resource&#8217;unu getirmektedir.<\/p>\n<p>Ayr\u0131ca elde edilen access token&#8217;\u0131 <a href=\"https:\/\/jwt.io\/\" rel=\"noopener noreferrer\" target=\"_blank\">jwt.io<\/a> adresinde decode ederek incelersek e\u011fer;<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme.jpg\" alt=\"IdentityServer4 Yaz\u0131 Serisi #16 - Merkezi \u00dcyelik Sistemi - \u00d6zel Identity Resource Ekleme\" width=\"939\" height=\"713\" class=\"aligncenter size-full wp-image-19096\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme.jpg 939w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme-300x228.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4-Yazi-Serisi-16-Merkezi-Uyelik-Sistemi-Ozel-Identity-Resource-Ekleme-768x583.jpg 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/a><br \/>\nilgili identity resource&#8217;un &#8216;scope&#8217; k\u0131sm\u0131na eklendi\u011fini g\u00f6zlemleyebilmekteyiz.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek uygulamay\u0131 indirebilmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/IdentityServer4Example-4.zip\">buraya<\/a> t\u0131klay\u0131n\u0131z.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, IdentityServer4 Yaz\u0131 Serisinin onbirinci makalesi olan Merkezi \u00dcyelik Sistemi Temelleri ba\u015fl\u0131kl\u0131 i\u00e7eri\u011fimizin 5. ad\u0131m\u0131nda Identity Resource \u00fczerine odaklanm\u0131\u015ft\u0131k ve \u00f6ntan\u0131ml\u0131 olan &#8216;OpenId&#8217; ve &#8216;Profile&#8217; bilgilerini ekleyerek kullan\u0131c\u0131 id\/subject id de\u011feriyle birlikte kullan\u0131c\u0131 profil&#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":18168,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3826],"tags":[3827,3918,3917,3887],"class_list":["post-19070","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-identityserver4","tag-identityserver4","tag-identityserver4-custom-identity-resource","tag-identityserver4-identity-resource","tag-merkezi-uyelik-sistemi"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19070","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=19070"}],"version-history":[{"count":29,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19070\/revisions"}],"predecessor-version":[{"id":19103,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19070\/revisions\/19103"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/18168"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=19070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=19070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=19070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}