在新起一個ASP.NET MVC專案時,我們可以使用含有identity的範本,來作為會員登入的系統,但是往往我們前台使用identity時,後台就會選擇使用Form Authentication,或者選擇空專案,全部使用Form Authentication。
這次的練習,我是採用前後台都是使用同一套identity,藉由Role的不同來切分前後台的使用者。
Step01.將identity 加入 RoleManager 功能
在App_Start的IdentityConfig.cs 加入
//增加角色管理員相關的設定 public class ApplicationRoleManager : RoleManager<IdentityRole> { public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore): base(roleStore) { } public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context) { return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>())); } }
在App_Start的 Startup.Auth.c s的 public void ConfigureAuth(IAppBuilder app) 加入
//增加角色的OwinContext app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
以上這兩個步驟,你的identity 就具備Role的功能了
Step02.在前後台的註冊頁加入Role的設定
public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false); //前台角色名稱 var RoleName = "Member"; //後台角色名稱 //var RoleName = "Admin"; //判斷角色是否存在 if (HttpContext.GetOwinContext().Gete<ApplicationRoleManager>().RoleExists(RoleName) == false) { //角色不存在,建立角色 var role = new IdentityRole(RoleName); await HttpContext.GetOwinContext().Gete<ApplicationRoleManager>().CreateAsync(role); } //將使用者加入該角色 await UserManager.AddToRoleAsync(user.Id, RoleName); return RedirectToAction("Index", "Home"); } AddErrors(result); } // 如果執行到這裡,發生某項失敗,則重新顯示表單 return View(model); }
Step03.增加一個 ActionFilter,名稱為 BackendAttribute
目的:如果前台登入者,因為角色名稱不是”Admin”,所以連到後台任何路徑都會被登出,踢到登入頁。
public class BackendAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentNullException(); //有設置AllowAnonymouse則不需要驗證 if (SkipAuthorization(filterContext)) return; var user = filterContext.RequestContext.HttpContext.User; var userIdentity = user.Identity; if (!userIdentity.IsAuthenticated) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Account", action = "Login" })); return; } if (!user.IsInRole("Admin")) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Account", action = "MemberLogOff" })); return; } } private static bool SkipAuthorization(AuthorizationContext filterContext) { return filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); } }
Step04.在後台增加一個 BaseController 套用 BackendAttribute
[Backend] public abstract class BaseController : Controller { public BaseController() { } }