1

我正在使用具有两种非常不同类型的用户的 ASP.NET MVC 构建一个 Web 应用程序。我将设计一个示例并说一种类型是内容生产者(发布者),另一种是内容消费者(订阅者)。

我不打算使用内置的 ASP.NET 授权东西,因为我的用户类型的分离是二分法,你要么是发布者,要么是订阅者,而不是两者。因此,内置授权比我需要的要复杂。另外,我正计划使用 MySQL。

我正在考虑将它们与枚举字段(技术上是 int 字段)一起存储在同一个表中。然后创建一个 CustomAuthorizationAttribute,我将在其中传入该页面所需的 userType。

例如,PublishContent 页面需要 userType == UserType.Publisher,因此只有 Publishers 可以访问它。因此,创建此属性使我可以访问 HttpContextBase,其中包含标准用户字段(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;
    }
}

或者有人认为我的整个方法有缺陷吗?

4

1 回答 1

3

我仍然会使用内置的 ASP.NET 表单身份验证,但只是根据您的需要对其进行自定义。

因此,您需要让您的 User 类实现 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;
    }
}

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;
}

HTH
查尔斯

于 2009-09-14T03:16:36.273 回答