Claims ile rol bazlı oturum yönetimi

ESRA ORHAN
3 min readAug 8, 2023

--

Evet basitce claims ile asp.net core da oturum yönetimi yapmıştık. şimdi rol bazlı bir sistemde bu nasıl olur dilim döndüğünce araştırmalarımla anlatmaya çalışacağım.

Öncelikle iki tabloya ihtiyacımız var. User ve UserRole adında iki tablom var.

 public class User 
{
public int UserID { get; set; }
public int UserRoleID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Password { get; set; }

}

UserRole tablosu:

public class UserRole
{
public int UserRoleID { get; set; }
public string RoleName { get; set; }
}

bu tablolara bir kaç değer ekleyelim. Ben kullanıcıların rollerini admin, kullanıcı olarak belirledim.

Admin ve kullanıcının vereceğim izinler farklı olacak ve tabi gireceği sayfalarda…

Form sayfasından Email ve şifre ile girecek ve tablomda eşlesen değere göre rolü zaten vermiş olacağım.

<div class="container">
<div class="row">
<div class="col-md-3">
<h3>Giriş yap</h3>
<form asp-action="Login" method="post">
<div class="form-group">
<label>Mail:</label>
<input type="text" class="form-control" id="email" name="email" />
</div>
<div class="form-group">
<label>Password:</label>
<input type="password" class="form-control" id="password" name="password" />
</div>
<div class="form-group">
<label></label>
<input type="submit" class="btn btn-primary" value="Login" />
</div>
</form>
</div>
</div>
</div>

eğer gelen admin ise görmesi gereken sayfaları belirleyeceğim.

Öncelikle Login işleminde nasıl ilerliyoruz ona bakalım. Sonrasında Startup.cs de nasıl configrasyon yapıyoruz o kodları bırakacağım. diğer yazımda tek tek açıklamıştım. o yüzden tekrar etmeyeceğim. Login Metodum şöyle :

 [HttpPost]
public IActionResult Login(string mail, string password)
{
//veritabanından kontrol ediyorum
var values = _userService.GetUserList().Data.FirstOrDefault(c => c.Email == mail && c.Password == password);
if (values != null)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,values.Email),
new Claim(ClaimTypes.Role,values.RoleName)
};
var useridentity = new ClaimsIdentity(claims, "AuthClaimsOrnek");
ClaimsPrincipal principal = new ClaimsPrincipal(useridentity);
HttpContext.SignInAsync(principal); //

TempData["message"] = "Şifre Doğru! Sayfaya Yönlendiriliyorsunuz...";
return RedirectToAction("Index", "Home");
}
else
{
TempData["messageerror"] = "Şifre Yanlış! ";
return View("Index");
}

return View("Index");
}

Burda eğer girilen mail ile eşlesen bir kullanıcım var ise mail ve rolünü Claim de yükleyip, ve onu da cokie ile devreye alacağız. Şöyle Claimda hiyerarşik bir örüntü var. Önce Claim oluşturuyoruz. ClaimsIdentity ile claimi içine alıyor. ve sonrasında ClaimsPrincipal ihtiyacımız oluyor ve o da identity içine alıyor ,en son oturum açan kullanıcıyı HttpContext.SignInAsync(principal); ile işaretlemiş oluyoruz. Yani dizilim şu şekilde kısaca :

Claim > ClaimsIdentity > ClaimsPrincipal

Login metodumuz bu şekildeydi. LogOut metodumuz da şöyle:

        public IActionResult LogOut()
{
// Mevcut kullanıcının kimlik bilgilerini temizleme
HttpContext.SignOutAsync();

return RedirectToAction("Index", "Login");
}

Authorize attribute ile de role göre kimlik doğrulamayı sağlayalım.Eğer Gelen Admin ise Home/Index Sayfasına erişebilsin.

Gelen kullanıcı login metodundan geçip claims ile işaretlendiyse , ClaimTypes.Role ile tuttugumuz degeri ile attribute içinde ki Roles ile eşleşiyor mu ona bakacak. Eğer degerler eşleşiyorsa sayfayı görmesine izin verecek. Eğer eşleşmiyor ise Startup.cs de belirlediğim AccessDenied Sayfasına yönlendirecek.

 [Authorize(Roles = "Admin")]
public class HomeController : Controller
{


public IActionResult Index()
{

Viewbag.Mesaj ="Hoşgeldin Admin!";
return View();
}
}

AccessDenied sayfasına gittiğini ekran görüntüsünü bırakıyorum.

Dönen Url şekli
Ve gelen sayfa… siz daha güzel bir tasarım ile yapabilirsiniz.

Gelelim Startup. cs de configrasyonlarımıza: ConfigureServices metodunun içerisine şu kodları ekleyelim.

            services.AddMvc(config => //proje seviyesinde yetkili login giriþini kontrol edebilceðiz. 
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
config.Filters.Add(new AuthorizeFilter(policy));
});

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x =>
{
x.LoginPath = "/Login/Index"; //login path verdik. Return Url yapacapımız dizin
x.AccessDeniedPath = "/Login/AccessDenied"; // Erişim reddedildi sayfası belirleyin.
});

services.ConfigureApplicationCookie(opts => // birden fazla yönlerdirme hatasý aldým bunun ile çözüldü
{
//Cookie settings
opts.Cookie.HttpOnly = true;
opts.ExpireTimeSpan = TimeSpan.FromMinutes(100);
opts.AccessDeniedPath = new PathString("/Login/AccessDenied/"); //yetkisi olmayan sayfalarda gideceði path
opts.LoginPath = "/Login/Index/";
opts.SlidingExpiration = true;
});

Configure metodunun içersine ise şu kodları eklememiz yapıyı ayaklandırmamıza yetecek.

  app.UseAuthentication();
app.UseAuthorization();

Özetle giren kullanıcın rolüne göre sayfaları kısıtlamış ve yetkilendirmiş olduk. ve bir yazının daha sonuna gelmiş olduk.

Sağlıkla kalın.

:)

--

--