不废话,从FilterAttribute开始:
抽象类FilterAttribute的是整个基础,Membership验证AuthorizeAttribute和ActionFilterAttribute继承它。
AuthorizeAttribute实现IAuthorizationFilter接口:
void OnAuthorization(AuthorizationContext filterContext);
AuthorizeAttribute的实现:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter {
private string _roles;
private string _users;
public string Roles {
get {
return _roles ?? String.Empty;
}
set {
_roles = value;
}
}
public string Users {
get {
return _users ?? String.Empty;
}
set {
_users = value;
}
}
public void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
IPrincipal user = filterContext.HttpContext.User;
if (!user.Identity.IsAuthenticated) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
return;
}
if (!String.IsNullOrEmpty(Users)) {
IEnumerable<string> validNames = SplitString(Users);
bool wasMatch = validNames.Any(name => String.Equals(name, user.Identity.Name, StringComparison.OrdinalIgnoreCase));
if (!wasMatch) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
return;
}
}
if (!String.IsNullOrEmpty(Roles)) {
IEnumerable<string> validRoles = SplitString(Roles);
bool wasMatch = validRoles.Any(role => user.IsInRole(role));
if (!wasMatch) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
private static IEnumerable<string> SplitString(string original) {
return from piece in original.Split(',')
let trimmed = piece.Trim()
where !String.IsNullOrEmpty(trimmed)
select trimmed;
}
}
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter {
private string _roles;
private string _users;
public string Roles {
get {
return _roles ?? String.Empty;
}
set {
_roles = value;
}
}
public string Users {
get {
return _users ?? String.Empty;
}
set {
_users = value;
}
}
public void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
IPrincipal user = filterContext.HttpContext.User;
if (!user.Identity.IsAuthenticated) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
return;
}
if (!String.IsNullOrEmpty(Users)) {
IEnumerable<string> validNames = SplitString(Users);
bool wasMatch = validNames.Any(name => String.Equals(name, user.Identity.Name, StringComparison.OrdinalIgnoreCase));
if (!wasMatch) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
return;
}
}
if (!String.IsNullOrEmpty(Roles)) {
IEnumerable<string> validRoles = SplitString(Roles);
bool wasMatch = validRoles.Any(role => user.IsInRole(role));
if (!wasMatch) {
filterContext.Cancel = true;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
private static IEnumerable<string> SplitString(string original) {
return from piece in original.Split(',')
let trimmed = piece.Trim()
where !String.IsNullOrEmpty(trimmed)
select trimmed;
}
}
首先这个类是sealed的,要实现其他的用户验证,不能直接继承重写。
OnAuthorization方法依次验证用户是否登录,如果有users参数或者roles参数,也会一一验证用户是否匹配。
ActionFilterAttribute 以前在preview、preview 2、3里,也可以写用户验证,重写ActionFilterAttribute 实现的 IActionFilter 接口成员 OnActionExecuting 即可。但是在Preview 4中,要写自己的用户验证,应该实现IAuthorizationFilter接口成员。