2013-08-30 44 views
4

使用使用.NET 4.5和IIS 8的MVC4应用程序。当权限检查失败时,是否有办法返回定制的未授权页面和401结果?如何返回401响应和自定义页面?

我也使用表单身份验证,并希望在用户未登录时重定向到登录页面,但在用户没有有效权限(即Admin)时重定向到未经授权的页面。

我还必须小心重定向,然后在成功重定向时获得200/301结果。

我需要返回401状态码并留在当前页面,同时还返回自定义未经授权的页面。

我有一个错误控制器返回一个未经授权的观点:

[ActionName("unauthorised")] 
    public ActionResult Http401() { 
     Response.StatusCode = 401; 
     Response.StatusDescription = "Unauthorised"; 
     Response.SuppressFormsAuthenticationRedirect = true; 
     return View("unauthorised"); 
    } 

而且我有我使用的尝试和调用401的一些方法,如果对权限的检查失败:

/// <summary>Method to invoke when user attempts action without relevant permission</summary> 
    /// <param name="httpContext">the httpcontext</param> 
    /// <returns>empty result</returns> 
    public ActionResult InvokeHttp401(HttpContextBase httpContext) { 
     Transfer("/error/unauthorised"); 
     return new EmptyResult(); 
    } 

    private void Transfer(string url) { 
     var uriBuilder = new UriBuilder(Request.Url.Scheme, Request.Url.Host, Request.Url.Port, Request.ApplicationPath); // Create URI builder 
     uriBuilder.Path += url; // Add destination URI 
     string path = Server.UrlDecode(uriBuilder.Uri.PathAndQuery); // Because UriBuilder escapes URI decode before passing as an argument 
     this.HttpContext.RewritePath(path, false); // Rewrite path 
     HttpContext.Server.TransferRequest(path, true); 
    } 

注意:我正在使用Server.TransferRequest,以便我可以尝试并返回当前URL上的401结果,而不会导致任何重定向。我在一个普通的ActionResult检查权限如下:

[Authorize] 
public ActionResult MyMethod() { 
    if (!UserHasPermission(Admin)) 
    return InvokeHttp401(HttpContext); 
    ...... 

凡authorize标签将重定向到登录,如果用户没有登录,其他权限检查。

通过上述设置,我可以返回401结果并保持当前的URL,但显示的是IIS 401错误而不是当前页面。

我也试图设置在我的web.config文件中的以下内容:

<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace"> 
     ..... 
     <error statusCode="401" responseMode="ExecuteURL" path="/Error/unauthorised" /> 
    </httpErrors> 

但是,这没有什么区别。如果我没有在我的Http401 ActionResult中设置状态码,但是它只是返回一个200结果,那么我能够获得未经授权的自定义页面。

我已经看过这个question的帖子(特别是蒂莫西的答案,它扩展了授权标签),但是没有像前面描述的那样没有类似的错误而无法得到任何这种工作。

任何人都可以帮忙吗?

回答

3

想通了最后 -

使用自定义的组合授权的标签,由Timothy在链接的问题建议,而这blog post,我能状态代码临时设置为418,然后改变它返回到Global.End_Request中的401。

我不得不做的最后一件事是添加418我的web.config和使用PassThrough模式:

<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough"> 
     <remove statusCode="404" /> 
     <error statusCode="404" responseMode="ExecuteURL" path="/Error/not-found" /> 
     <remove statusCode="500" /> 
     <error statusCode="500" responseMode="ExecuteURL" path="/Error/error" /> 
     <remove statusCode="401" /> 
     <error statusCode="401" responseMode="ExecuteURL" path="/Error/unauthorised" /> 
    </httpErrors> 

而且我得到了相同的URL 401结果,以及我的自定义视图。

+1

随着物联网的兴起,我期望和希望有人会聪明地实现一个咖啡壶,随茶壶发送一个418,当你把它放在持有人。另外我没有看到你在web.config中添加418 – Luminous

相关问题