ASP.NET MVC自定义授权
-
07-07-2019 - |
题
我正在使用ASP.NET MVC构建一个Web应用程序,它有两种非常不同类型的用户。我会设想一个例子,并说一种类型是内容制作者(发布者),另一种是内容消费者(订阅者)。
我不打算使用内置的ASP.NET授权内容,因为我的用户类型的分离是一种二分法,你既可以是发布者,也可以是订阅者,而不是两者。因此,内置授权比我需要的更复杂。另外我打算使用MySQL。
我在考虑将它们存储在具有枚举字段的同一个表中(技术上是一个int字段)。然后创建一个CustomAuthorizationAttribute,在那里我传入该页面所需的userType。
例如,PublishContent页面需要userType == UserType.Publisher,因此只有Publishers才能访问它。因此,创建此属性使我可以访问HttpContextBase,其中包含标准的User字段(IPrincipal类型)。如何将UserType字段添加到此IPrincipal中?那么,我的属性看起来像是:
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表单身份验证,但只是根据您的需要进行自定义。
因此,您需要让User类实现IPrincipal接口,然后编写自己的自定义cookie处理。然后,您只需使用内置的[授权]属性。
目前我有类似以下内容......
在我的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;
}
}
AccountController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(LogOnForm logOnForm)
{
try
{
if (ModelState.IsValid)
{
WebUser user = AccountService.GetWebUserFromLogOnForm(logOnForm);
Response.Cookies.Add(FormsAuth.GetAuthCookie(user, logOnForm.RememberMe));
return Redirect(logOnForm.ReturnUrl);
}
}
catch (ServiceLayerException ex)
{
ex.BindToModelState(ModelState);
}
catch
{
ModelState.AddModelError("*", "There was server error trying to log on, try again. If your problem persists, please contact us.");
}
return View("LogOn", logOnForm);
}
最后我的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结果 查尔斯
不隶属于 StackOverflow