使用自定义身份验证自定义AuthorizeAttribute

Jus*_*tin 10 asp.net-mvc authorize-attribute custom-authentication

我使用ASP.NET MVC 4 Web应用程序作为一些WCF服务的前端.所有用户登录/注销和会话控制都在后端完成.MVC应用程序应该只存储具有会话ID的单个cookie.我的客户端不允许使用表单身份验证,所有内容都必须自定义.

我在web.config中设置了以下内容:

  <system.web>
...
    <authentication mode="None" />
  </system.web>

  <system.webServer>
    <modules>
...
      <remove name="FormsAuthentication" />
...    
    </modules>
  </system.webServer>
Run Code Online (Sandbox Code Playgroud)

我还有一个全局过滤器:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // Force all actions to request auth. Only actions marked with [AllowAnonymous] will be allowed.
        filters.Add(new MyAuthorizeAttribute());
    }
}
Run Code Online (Sandbox Code Playgroud)

在Global.asax中调用

   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
Run Code Online (Sandbox Code Playgroud)

我用[AllowAnonymous]标记了每个不需要授权的控制器和操作.

现在我必须实现MyAuthorizeAttribute.我尝试了一些教程,但没有一个完全符合我的场景.

基本上,我必须为每个操作处理以下方案:

  1. 如果存在有效的cookie,则应将当前请求视为已授权(不会检查任何角色,只有一种用户).
  2. 如果没有cookie,我应该覆盖默认的MVC处理程序(尝试加载帐户/登录)并将用户重定向到Home/Index页面,并显示用户应该登录的消息.
  3. 如果WCF方法调用抛出FaultException我们的自定义SecurityFault说会话已经过期(SecurityFault有一个包含异常原因的自定义枚举字段),我应该销毁我的自定义会话cookie并再次将用户重定向到Home/Index页面用户应该登录的消息,因为他的上一个会话已过期.对于所有其他SecurityFaults,我可以让它们通过 - 我有一个全局错误处理程序.

据我所知,我需要覆盖AuthorizeCore(检查我的cookie以查看会话是否存在且仍然有效)和HandleUnauthorizedRequest(将用户重定向到Home/Index而不是默认的Login页面).

对于重定向,我试过:

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {            
        base.HandleUnauthorizedRequest(filterContext);
        filterContext.Result = new RedirectResult("/Home/Index/NeedsLogin");
    }
Run Code Online (Sandbox Code Playgroud)

这似乎处理第二个罚款的情况(我不确定那个基本呼叫,但它是否需要?).

对于第一种情况,我需要实现AuthorizeCore.我不确定,如何正确地做到这一点.我已经看到AuthorizeAttribute有一些代码用于处理缓存情况,也许还有更多隐藏的功能,我不想打破它.

对于第三种情况,我不确定MyAuthorizeAttribute是否能够处理它.AuthorizeAttribute可以捕获Action内部发生的异常,或者我必须在我的全局错误处理程序中处理SecurityFault.SessionExpired情况吗?

Jiv*_*gie 7

不完全确定我得到它但是如果你创建一个继承自System.Web.MVC.Authorize属性的自定义授权过滤器,就像这样.

    public class CustomAuthorize : AuthorizeAttribute
    {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (CookieIsValid(filterContext.Request.Cookies["cookieyouwant"])
        {
             filterContext.Result = new RedirectResult("DestUrl");
        }
        else
        {
            filterContext.Result = new RedirectResult("/Home/Index/NeedsLogin");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后装饰你需要使用这个授权的方法来做到这一点?