У меня есть простой метод, который защищен
[PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
protected void lnkClearCache_Click(object sender, EventArgs e)
{
...
}
Если щелкнуть по нему без роли, будет сгенерировано System.Security.SecurityException: Request for principal permission failed.
, как и ожидалось.
Я использую ELMAH для ведения журнала ошибок, и у меня есть специальное событие ELMAH в файле global.asax для передачи на страницы ошибок способами, сохраняющими коды состояния, которые работают правильно.
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, а затем позволял завершить весь запрос, а затем после завершения запроса отбрасывал ответ приложения и вместо этого отвечал пользовательской ошибкой по умолчанию.
Когда я отлаживаю, я разбиваю 2 отдельных исключения для PrincipalPermission, является ли это просто повторным броском .NET, я не уверен, но мой код .NET никогда не видит 2-й бросок, как и ELMAH. Я всегда получаю один ответ, регистрируется одна ошибка, но URL-адрес, который, наконец, отображается в браузере, является URL-адресом по умолчанию, а не URL-адресом 403, на который я специально перешел server.transferred. Если я просматриваю безопасное /местоположение, я правильно получаю страницу с ошибкой 403.