ASP.NET身份認證過程
在ASP.NET中,身份認證過程分為兩個部分:
- 認證:識別當前請求的用戶是否為可識別(已登錄)用戶骚勘;
- 授權(quán):根據(jù)認證中識別的用戶決定是否允許當前用戶的請求訪問指定的資源。
其中Forms認證由FormsAuthenticationModule
實現(xiàn)菠剩,URL授權(quán)檢查由UrlAuthorizationModule
實現(xiàn)
認證(登錄與登出的實現(xiàn))
//登錄
public static bool SignOn(string username,string password,bool persist)
{
InterfaceUserService userService = null;
if (userService == null)
{
userService = new UserService();
}
//此處省略參數(shù)合法性驗證
//驗證用戶名密碼是否正確溯警,若正確則設(shè)置Cookie
if (userService.Validate(username, password))
{
SetAuthenticationTicket(username, persist);
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(username,persist);
HttpContext.Current.Response.Cookies.Remove(authCookie.Name);
HttpContext.Current.Response.Cookies.Add(authCookie);
return true;
}
else
{
return false;
}
}
//登出
public static void LogOut()
{
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName);
//使cookie強制過期
authCookie.Expires = DateTime.Now.AddYears(-30);
authCookie.Path = HttpContext.Current.Request.ApplicationPath;
HttpContext.Current.Response.Cookies.Add(authCookie);
//退出登錄后執(zhí)行頁面重定向到主頁操作
}
//獲取登錄用戶名部分代碼,AuthenticationMoudel類中的UserName屬性
public string UserName
{
get
{
var httpContext = HttpContext.Current;
if (httpContext != null &&
httpContext.Request != null &&
httpContext.Request.IsAuthenticated)
{
try
{
return httpContext.User.Identity.Name;
}
catch
{
}
}
else
{
return null;
}
}
}
對于Forms認證离唬,我們需要在Web.config
的<system.web>節(jié)點部分添加以下內(nèi)容:
<authentication mode="Forms" >
<forms cookieless="UseCookies"
name="LoginCookieName"
loginUrl="~/Default.aspx"/>
</authentication>
該部分指定了身份驗證模式為Forms,Cookie的使用方式呛凶,Cookie名稱男娄,默認登錄頁面(當未認證或認證失敗時會跳轉(zhuǎn)到默認登錄頁)。
為何要設(shè)置Cookie呢漾稀?
因為Forms的身份認證是通過Cookie來維持的模闲,且該Cookie是加密過的HttpOnly Cookie(無法在瀏覽器端更改的Cookie)
授權(quán)
授權(quán)的問題就是用戶與用戶組權(quán)限的問題,根據(jù)當前登錄用戶及其所屬用戶組的權(quán)限來判斷當前用戶的請求是否能夠訪問目標資源崭捍。
Forms身份認證的授權(quán)也需要在Web.config
的<system.web>節(jié)點中配置尸折,示例如下:
<authorization>
<allow users="admin"/>
<deny users="*"/>
</authorization>
自定義驗證用戶登錄
一、Filter
ASP.NetMVC模式自帶的過濾器Filter殷蛇,是一種聲明式編程方式实夹,支持四種過濾器類型,分別是:Authorization(授權(quán))粒梦,Action(行為)亮航,Result(結(jié)果)和Exception(異常)。
? 表1
過濾器類型 | 接口 | 描述 |
---|---|---|
Authorization | IAuthorizationFilter | 此類型(或過濾器)用于限制進入控制器或控制器的某個行為方法 |
Action | IActionFilter | 用于進入行為之前或之后的處理 |
Result | IResultFilter | 用于返回結(jié)果的之前或之后的處理 |
Exception | IExceptionFilter | 用于指定一個行為匀们,這個被指定的行為處理某個行為方法或某個控制器里面拋出的異常 |
但是默認實現(xiàn)它們的過濾器只有三種缴淋,分別是ActionFilter(方法),Authorize(授權(quán))泄朴,HandleError(錯誤處理)重抖;各種信息如下表所示:
? 表2
過濾器 | 類名 | 實現(xiàn)接口 |
---|---|---|
Authorize | AuthorizeAttribute | IAuthorizationFilter |
HandleError | HandleErrorAttribute | IExceptionFilter |
自定義 | ActionFilterAttribute | IActionFilter和IResultFilter |
ASP.NET默認的身份驗證過濾器是[Authorize]對應AuthorizeAttribute類
二、通過自定義過濾器實現(xiàn)登錄驗證
表2中只寫了實現(xiàn)表1中的接口祖灰,實際上ActionFilterAttribute繼承了FilterAttribute钟沛、IActionFilter和IResultFilter.
具體實現(xiàn)方法
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthenticatedAttribute:FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//此處AuthenticationMoudel類中的UserName屬性已在認證模塊中定義
if (string.IsNullOrEmpty(AuthenticationMoudel.UserName))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
最后在需要登錄驗證的地方打下自定義的Filter的標簽[Authenticated]
[Authenticated]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "歡迎使用 ASP.NET MVC!";
return View();
}
}
三、使用系統(tǒng)的AuthorizeAttribute驗證登錄
public class AuthenticationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
//base.OnAuthorization(filterContext);
//如果控制器沒有加AllowAnonymous特性或者Action沒有加AllowAnonymous特性才檢查
if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true))
{
//此處寫判斷是否登錄的邏輯代碼
HttpCookie cookie = filterContext.HttpContext.Request.Cookies["Member"];
if (!(cookie!=null && cookie.Values["name"] == "test" && cookie.Values["pass"] == "123")) {
filterContext.Result = new RedirectResult("/Member/Login");
}
}
}
}
若加了Authentication過濾器的控制器中有需要匿名訪問的方法局扶,可以在方法前面添加[AllowAnonymous]過濾器
另一種寫法是繼承FilterAttribute 并實現(xiàn)接口IAuthorizationFilter恨统,方式與系統(tǒng)的AuthorizeAttribute類似
參考文章:1. 細說ASP.NET Forms身份認證
菜鳥一枚叁扫,還望大家多多指教
補充:在運行上述代碼時,發(fā)現(xiàn)配置了Forms認證后登錄不成功延欠,匿名用戶訪問需要認證的頁面時不能跳轉(zhuǎn)到登錄頁面陌兑,解決方案如下:
在Web.Config文件的<system.webServer>節(jié)添加下面兩句
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
剛開始我只有第一句<remove name="FormsAuthentication" />
沈跨,添加第二句后解決問題由捎。