如何在MVC中实现自定义验证时终止请求处理?

问题描述:

在我的MVC2应用程序中,我希望大多数请求使用Forms身份验证,并请求某些特定的URI来使用我的自定义身份验证。为了做到这一点,我添加了FormsAuthentication_OnAuthenticate()方法,并在内部检查了URI,并且如果它是其中一个独占的URI,我想检查请求标头中的用户名和密码。如何在MVC中实现自定义验证时终止请求处理?

问题是如果提供的凭据错误,如何终止请求。

我尝试:

HttpContext context = args.Context; 

context.Response.Write("Wrong credentials"); 
context.Response.StatusCode = 401; 
context.Response.End(); 

但一旦出现这种情况的请求转发到在web.config中指定下

<authentication mode="Forms"> 
     <forms loginUrl="~/LogOn"/> 
</authentication> 

我想请求被终止的URI - 使得该响应被发送到客户端并且连接被关闭。我如何实现这一目标?

只要您发送401状态码,Forms Authentication模块就会拦截此代码并自动重定向到登录页面。在ASP.NET MVC中处理身份验证的正确方法是使用[Authorize]属性。如果你不希望它重定向到登录页面,而是显示出一些观点,你可以写一个自定义的授权属性,并覆盖HandleUnauthorizedRequest方法:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new ViewResult 
     { 
      ViewName = "~/Views/Shared/unauthorized.cshtml" 
     }; 
    } 
} 

UPDATE:

另外要覆盖HandleUnauthorizedRequest,您可以覆盖允许您执行自定义身份验证的AuthorizeCore方法。

+0

我不想重定向到视图 - 这些地址是针对程序化请求的,所以我必须将一些魔术预定义的字符串提供给响应并关闭它。所以我不想拦截Forms Auth模块。 – sharptooth

+0

@sharptooth,如果你不想重定向到一个视图,只需返回一个空的结果或任何客户端的期望:'filterContext.Result = new EmptyResult();' –

+0

好吧,但我该如何调用我的自定义验证方式? – sharptooth

保护您的应用程序的更简单的方法是使用PrincipalPermissionAttribute,您可以将其应用于整个控制器,或者仅应用于控制器上的操作。例如。

[PrincipalPermission(SecurityAction.Demand, Role="Administrator")] public class AdminController : Controller { ... }

[PrincipalPermission(SecurityAction.Demand, Role="Administrator")] public ActionResult DeleteUser(int id) { ... }

你可以找到更多信息in this article

+0

如果您阅读了评论,您会发现这确实不是一个好主意,因为PrincipalPermssion不使用CodeSecurity。这是一个更低的水平,需要你执行一堆其他的事情。 –