我有一个简单的方法可以保证

[PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
protected void lnkClearCache_Click(object sender, EventArgs e)
{
    ...
}

如果在没有角色的情况下单击此按钮,则会生成预期的System.Security.SecurityException: Request for principal permission failed.

我使用ELMAH处理错误的日志记录,并且我在global.asax中有一个自定义ELMAH事件,以保留状态代码正常运行的方式转移到错误页面。
private void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
    var customErrorsSection = GetCustomErrorsSection();
    var error = args.Entry;

    string statusCode = error.Error.StatusCode.ToString();

    if (statusCode == "0" && error is security exception)
        statusCode = "403";

    var errorSection = customErrorsSection.Errors[statusCode];
    string redirectUrl = errorSection == null ?
            customErrorsSection.DefaultRedirect : errorSection.Redirect;


    RespondWithServerError(error.Id, redirectUrl, statusCode);
}

一切正常,并且可以重定向到我的错误页面,该页面正常运行,但是未按预期显示内容。我立即收到第二个关于错误页面的请求,但是这次使用customErrorsSection.DefaultRedirect的值,该值并非以我能看到的任何方式来自我的代码。

据我所知,这几乎就像.NET为PrincipalPermission引发异常然后让整个请求完成一样,然后在请求完成后,它丢弃了应用程序响应,而是以默认的自定义错误响应。

当我调试时,我确实中断了PrincipalPermission的2个单独的异常,无论这是否只是.NET的重新抛出,我不确定,但我的.NET代码永远不会看到第二次抛出,ELMAH也不会。我总是以单个响应结束,记录单个错误,但是最终呈现给浏览器的URL是默认URL,而不是我专门server.transfer到的403 URL。如果浏览到安全的/location,则正确显示403错误页面。

最佳答案

我完全不知道问题出在哪里。但是我正在使用类似的东西,对我来说,这种解决方案(最小化)效果很好。

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        Dim er = HttpContext.Current.Error
        If er.GetType.Equals(GetType(System.Security.SecurityException)) Then
            HttpContext.Current.Response.Redirect(FormsAuthentication.LoginUrl & "?ReturnUrl=" & HttpContext.Current.Request.Path)
        End If
    End Sub

那超出了global.asax

但是在某些地方,我没有重定向,只是使用try and catch securityexception来显示用户,不允许他执行此类操作。

10-04 16:46