在新起一個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()
{
}
}
