ASP.NET MVC自定义授权
我正在使用ASP.NET MVC构建一个web应用程序,它有两种截然不同的用户类型。我将设计一个示例,其中一种类型是内容生产者(出版商),另一种类型是内容消费者(订阅者) 我不打算使用内置的ASP.NET授权工具,因为我的用户类型的分离是一种二分法,你要么是发布者,要么是订阅者,而不是两者兼而有之。因此,内置授权比我需要的更复杂。另外,我计划使用MySQL 我在考虑将它们存储在同一个带有enum字段(技术上是int字段)的表中。然后创建一个CustomAuthorizationAttribute,我将在其中传入该页面所需的用户类型 例如,PublishContent页面需要userType==userType.Publisher,因此只有发布者才能访问它。因此,创建此属性使我能够访问HttpContextBase,它包含标准用户字段(类型为IPrincipal)。如何将我的UserType字段放到这个IPrincipal上?那么,我的属性将如下所示:ASP.NET MVC自定义授权,asp.net,mysql,asp.net-mvc,authorization,authorize,Asp.net,Mysql,Asp.net Mvc,Authorization,Authorize,我正在使用ASP.NET MVC构建一个web应用程序,它有两种截然不同的用户类型。我将设计一个示例,其中一种类型是内容生产者(出版商),另一种类型是内容消费者(订阅者) 我不打算使用内置的ASP.NET授权工具,因为我的用户类型的分离是一种二分法,你要么是发布者,要么是订阅者,而不是两者兼而有之。因此,内置授权比我需要的更复杂。另外,我计划使用MySQL 我在考虑将它们存储在同一个带有enum字段(技术上是int字段)的表中。然后创建一个CustomAuthorizationAttribute
public class PublisherAuthorizationAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.User.Identity.IsAuthenticated)
return false;
if (!httpContext.User.Identity.UserType == UserTypes.Publisher)
return false;
return true;
}
}
或者有人认为我的整个方法有缺陷吗?我仍然会使用内置的ASP.NET表单身份验证,但只是根据您的需要对其进行自定义 因此,您需要让您的用户类实现IPrincipal接口,然后编写自己的自定义cookie处理。然后,只需使用内置的[Authorize]属性即可 目前,我有一些类似的如下 在我的global.asax中
protected void Application_AuthenticateRequest()
{
HttpCookie cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie == null)
return;
bool isPersistent;
int webuserid = GetUserId(cookie, out isPersistent);
//Lets see if the user exists
var webUserRepository = Kernel.Get<IWebUserRepository>();
try
{
WebUser current = webUserRepository.GetById(webuserid);
//Refresh the cookie
var formsAuth = Kernel.Get<IFormsAuthService>();
Response.Cookies.Add(formsAuth.GetAuthCookie(current, isPersistent));
Context.User = current;
}
catch (Exception ex)
{
//TODO: Logging
RemoveAuthCookieAndRedirectToDefaultPage();
}
}
private int GetUserId(HttpCookie cookie, out bool isPersistent)
{
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
isPersistent = ticket.IsPersistent;
return int.Parse(ticket.UserData);
}
catch (Exception ex)
{
//TODO: Logging
RemoveAuthCookieAndRedirectToDefaultPage();
isPersistent = false;
return -1;
}
}
最后,我的FormsAuthService:
public HttpCookie GetAuthCookie(WebUser webUser, bool createPersistentCookie)
{
var ticket = new FormsAuthenticationTicket(1,
webUser.Email,
DateTime.Now,
DateTime.Now.AddMonths(1),
createPersistentCookie,
webUser.Id.ToString());
string cookieValue = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
{
Path = "/"
};
if (createPersistentCookie)
authCookie.Expires = ticket.Expiration;
return authCookie;
}
HTHs查尔斯这将给MVC带来一个不稳定的混乱局面。绝对不是正确的方法。不稳定的混乱?几乎没有。这是非常短视的说法。
AccountService
和FormsAuth
服务都是注入AccountController
的接口,使其完全可测试。其他一切都依赖于FormsAuthentication(你还怎么做formsauth?),正如你应该知道的,这是众所周知的难以测试的——正如默认的ASP.NET MVC项目所指出的那样。当然,您可以提取对服务的FormsAuthentication调用,但考虑到对服务的调用在哪里,这真的能实现什么?
public HttpCookie GetAuthCookie(WebUser webUser, bool createPersistentCookie)
{
var ticket = new FormsAuthenticationTicket(1,
webUser.Email,
DateTime.Now,
DateTime.Now.AddMonths(1),
createPersistentCookie,
webUser.Id.ToString());
string cookieValue = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
{
Path = "/"
};
if (createPersistentCookie)
authCookie.Expires = ticket.Expiration;
return authCookie;
}