Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

IdentityServer4 Yazı Serisi #17 – Merkezi Üyelik Sistemi – Client Uygulaması İçin Role Based Authorization

Merhaba,

IdentityServer4 Yazı Serisinin bu onyedinci makalesinde, geliştirilen client uygulaması için rol tabanlı yetkilendirmeyi ele alacağız.

Client uygulamasında rol tabanlı yetkilendirme için esasında bildiğimiz claim tabanlı bir yetkilendirme yapmamız gerekecektir. Burada MVC uygulamalarında kullandığımız klasik claim bazlı doğrulamadan ziyade, IdentityServer4 yapılanmasında oluşturulan ve kullanıcı ve client ile ilişkilendirilen bir claim’i, client uygulamasında role tabanlı yetkilendirme ile ilişkilendirme üzerine çalışma sergileyeceğiz. Dolayısıyla öncelikle o rolü temsil eden bir identity resource oluşturacak ve ardından bu identity resource’ü kullanıcı ve client tanımlamalarıyla ilişkilendirecek ve en nihayetinde client uygulaması üzerinden talep edecek ve role olarak kullanacağız.

İçerikte pratik örneklendirmeyi yazı serimiz boyunca geliştirdiğimiz uygulama üzerinden sağlayacağız. Uygulamanın son haline erişebilmek için buraya tıklayınız. Hadi buyrun başlayalım…

  • Adım 1
    İlk olarak Auth Server’daki ‘Config.cs’ dosyasında identity resource oluşturarak başlayalım.

            public static IEnumerable<IdentityResource> GetIdentityResources()
            {
                return new List<IdentityResource>
                {
                    .
                    .
                    .
                    new IdentityResource {
                        Name = "Roles",
                        DisplayName = "Roles",
                        Description = "Kullanıcı rolleri",
                        UserClaims = { "role" }
                    }
                };
            }
    

    Oluşturulan identity resource’e göz atarsanız eğer ‘Roles’ adı altında ‘role’ isminde bir claim oluşturulmuştur.

  • Adım 2
    Ardından yine ‘Config.cs’ dosyasında tanımlı olan test kullanıcılarına, yukarıda oluşturulan identity resource’de ki ‘role’ claim’ini ekleyelim ve belirli roller atayalım.

            public static IEnumerable<TestUser> GetTestUsers()
            {
                return new List<TestUser> {
                    new TestUser {
                        SubjectId = "test-user1",
                        Username = "test-user1",
                        Password = "12345",
                        Claims = {
                            new Claim("name","test user1"),
                            new Claim("given_name","test user1 given"),
                            new Claim("website","https://wwww.testuser1.com"),
                            new Claim("gender","1"),
                            new Claim("position" , "Test Kullanıcısı 1"),
                            new Claim("authority", "Test 1"),
                            new Claim("role", "admin")
                        }
                    },
                    new TestUser {
                        SubjectId = "test-user2",
                        Username = "test-user2",
                        Password = "12345",
                        Claims = {
                            new Claim("name","test user2"),
                            new Claim("website","https://wwww.testuser2.com"),
                            new Claim("gender","0"),
                            new Claim("position" , "Test Kullanıcısı 2"),
                            new Claim("authority", "Test 2"),
                            new Claim("role", "moderator")
                        }
                    }
                };
            }
    

    görüldüğü üzere ‘test-user1’e ‘admin’, ‘test-user2’ye ise ‘moderator’ rolleri verilmiştir.

  • Adım 3
    Şimdi de client’ın kullanıcılarda tanımlanan bu rollere erişebilmesi için izin verilmesi gerekmektedir. Bunun için yine ‘Config.cs’ dosyasında tanımlanan client’lar da aşağıdaki gibi ilgili identity resource scope olarak eklenmesi gerekmektedir.

            public static IEnumerable<Client> GetClients()
            {
                return new List<Client>
                {
                    .
                    .
                    .
                    new Client
                            {
                                .
                                .
                                .
                                AllowedScopes = {
                                    IdentityServerConstants.StandardScopes.OpenId,
                                    IdentityServerConstants.StandardScopes.Profile,
                                    IdentityServerConstants.StandardScopes.OfflineAccess,
                                    "Garanti.Write",
                                    "Garanti.Read",
                                    "PositionAndAuthority",
                                    "Roles"
                                                },
                                .
                                .
                                .
                            }
                };
            }
    
  • Adım 4
    Ve son olarak ilgili client uygulamasının ‘Startup.cs’ dosyasında, oluşturulan identity resource, scope olarak eklenmeli ve böylece talep edilmelidir.

        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                .
                .
                .
                .AddOpenIdConnect("oidc", _ =>
                {
                    .
                    .
                    .
                    _.Scope.Add("Roles");
                    _.ClaimActions.MapUniqueJsonKey("role", "role");
                    _.TokenValidationParameters = new TokenValidationParameters
                    {
                        RoleClaimType = "role"
                    };
                });
            }
        }
    

    Yukarıdaki kod bloğunda 15. satıra göz atarsanız eğer talep edilen(13. satır) ve ‘role’ değeri ile eşleştirilen(14. satır) bu claim değerini client’ın kimlik yetkilendirmesi için kullanacağını bildirmekteyiz.

Artık client uygulamasında rol bazlı yetkilendirmenin geçerli olması istinilen sayfaları ‘Authorize’ attribute’u ile aşağıdaki gibi işaretleyebiliriz.

    public class BakiyeController : ControllerBase
    {
        [Authorize(Roles = "admin")]
        public IActionResult BakiyeGor()
        {
            return Ok(1000);
        }
        [Authorize(Roles = "moderator")]
        public IActionResult HareketDokumu()
        {
            return Ok("Hareket dökümü");
        }
        [Authorize(Roles = "admin, moderator")]
        public IActionResult CiktiAl()
        {
            return Ok("Döküman alınıyor");
        }
    }

Yukarıdaki kod bloğunda görüldüğü üzere ‘Bakiye(Controller)’ içerisindeki ‘BakiyeGor’ action’ı ‘admin’, ‘HareketDokumu’ action’ı ‘moderator’ ve ‘CiktiAl’ action’ı ise her iki rolden birini gerektirmektedir. Biz ise ‘test-user1’e ‘admin’, ‘test-user2’ye ise ‘moderator’ rollerini vermiştik. Şimdi gelin test edelim.

test-user1 test-user2
IdentityServer4 Yazı Serisi #17 – Merkezi Üyelik Sistemi – Client Uygulaması İçin Role Based Authorization IdentityServer4 Yazı Serisi #17 – Merkezi Üyelik Sistemi – Client Uygulaması İçin Role Based Authorization

Dikkat ederseniz kullanıcılar rolleri olmayan sayfalara erişmeye çalıştıkları zaman Account/AccessDenied sayfasına yönlendirilmektedirler. Böyle bir durumda ya ilgili sayfa tasarlanmalı ya da aşağıdaki gibi client uygulamasının ‘Startup.cs’ dosyasında farklı bir sayfaya yönlendirme gerçekleştirilmelidir.

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            .
            .
            .
            .AddCookie("OnlineBankamatikCookie", options => options.AccessDeniedPath = "/home/accessdenied")
            .
            .
            .
        }
    }

İşte IdentityServer4 mimarisinde rol tabanlı yetkilendirme bu şekilde gerçekleştirilmektedir.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Örnek projeyi indirmek için buraya tıklayınız.

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Mehmed Emre dedi ki:

    Yazınızı okumadım ama her akşam bildirim geliyor. Azminizi tebrik ediyorum. Maşallah nazar değmesin.:D Bu arada içeriklerinizden çok faydalanıyorum hakkınızı helal edin.

  2. Ali Namlı dedi ki:

    Yazı için teşekkürler çok faydalı oldu.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir