9-3.ASP.NET Core MVC 入門教學 - 角色權限和登入期限

ASP.NET Core MVC 入門教學

這一節要來教角色權限的設定,所以這邊有修改一下資料庫的資料表,所以要跟著做的要更新一下。

角色權限是什麼?就是每個帳號會有不同的權限,每個角色各自會對應不同的權限

所以會去記錄每個帳號個擁有那些角色,就會有對應的權限功能可以使用

首先這邊新增了一個帳號角色紀錄的資料表

這邊設定了Tallkai擁有Select跟Edit的角色,Test1擁有Select的角色,而Test2則沒有擁有角色

資料庫這邊資料準備好了之後,我們就要給登入的帳號設定對應的角色

public IActionResult Index(LoginDto value)
{
    var employee = _kcgContext.Employee
        .FirstOrDefault(e => e.Account.ToLower() == value.Account.ToLower()
        && e.Password == value.Password);

    if (employee != null)
    {
        var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, employee.Account),
                    new Claim("FullName", employee.Name)
                };

        var roles = _kcgContext.Role
            .Where(r => r.EmployeeId == employee.EmployeeId)
            .Select(r => r.Name);

        foreach (var role in roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));

        return RedirectToAction("Index", "Home");
    }
    else
    {
        ViewBag.Message = "帳號或密碼錯誤";
        return View(value);
    }
}

這邊我帳號密碼也存在資料庫了,所以有修改一下登入驗證的程式

var roles = _kcgContext.Role
    .Where(r => r.EmployeeId == employee.EmployeeId)
    .Select(r => r.Name);

foreach (var role in roles)
{
    claims.Add(new Claim(ClaimTypes.Role, role));
}

接著這一段就是把該帳號的角色撈出來後,一一寫進claims紀錄該登入者擁有那些角色

角色設定完了之後,我們就要換到controller去設定對應的權限

namespace Kcg.Controllers
{
    [Authorize(Roles = "Select")]
    public class NewsController : Controller
    {
    }
}

我們在NewsController上方放置[Authorize(Roles = "Select")]標籤

就代表說這個controller所有頁面,都需要Select角色才能進入

這時我們可以試試使用沒有Select權限的Test2然後進進看News頁面

就會發現找不到網頁,被拒絕進入,代表權限有生效,可以再試試Talllkai或Test1就可以正確進入

但這樣有點不貼心,我們應該將沒有權限的人導回首頁之類的,所以可以到program.cs進行設定

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login"; // 未登入會導向此頁
        options.AccessDeniedPath = "/Home/Index"; // 沒有權限會導向此頁
    });

我們將沒有權限時會導回登入的首頁,可以再試試點擊news連結,發現會自動導回首頁

但這樣依然不夠貼心,我們應該在沒有權限時把沒權限的連結給隱藏起來

@if (User.IsInRole("Select"))
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="" asp-controller="News" asp-action="Index">NewsIndex</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="" asp-controller="News2" asp-action="Index">NewsIndex2</a>
    </li>
}

這樣就是當使用者有Select權限時,才能看到該連結,此時就會看到New連結看不到了,但切換到Talllkai或Test1就會出現了

用如此簡單的標籤,就可以輕鬆地去限制不同帳號不同權限時,可以使用的功能

最後要來講登入的期限該怎麼設定

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login"; // 未登入會導向此頁
        options.AccessDeniedPath = "/Home/Index"; // 沒有權限會導向此頁
        options.ExpireTimeSpan = TimeSpan.FromSeconds(2);
    });

我們這邊為了測試就設定2秒期限,試著登入後過兩秒重新整理,就會被發現踢回登入頁面了,代表之前的登入已失效了

 

範例檔:下載




Copyright © 凱哥寫程式 2022 | Powered by TalllKai ❤