I have a simple method that is secured
[PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
protected void lnkClearCache_Click(object sender, EventArgs e)
{
...
}
If this is clicked without the role, it generates a System.Security.SecurityException: Request for principal permission failed.
as expected.
I use ELMAH to handle logging for my errors, and I have a custom ELMAH event in my global.asax to transfer to the error pages in way开发者_JAVA百科s that preserve status codes which works correctly.
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);
}
This works all well and fine and redirects to my error page which works properly, however instead of displaying the content as expected. I immediately get a second request for the error page but this time using the value of customErrorsSection.DefaultRedirect that does not come from my code in any way that I can see.
As far as I can tell it's almost as if when .NET raises an exception for PrincipalPermission and then lets the entire request complete, then after the request is complete it throws away the application response and instead responds with the default custom error.
When I'm debugging I do break on 2 separate exceptions for PrincipalPermission, whether this is a just a rethrow by .NET I'm not sure but my .NET code never sees the 2nd throw, nor does ELMAH. I always end up with a single response, single error logged, but that the url that finally renders to the browser is the default url and not 403 url that I specifically server.transferred to. If I browse to a /location that is secure I properly get the 403 error page.
I don´t excactly know where the problem is. But i´´m using something similar and for me this solution (minimized) works great.
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
That´s out of global.asax
But on some places I don´´t redirect, and just using try and catch the securityexception to display the user, that he is not allowed to perform such action.
精彩评论