Я использую проверку подлинности с помощью форм в моем приложении asp.net (3.5). Я также использую роли, чтобы определить, какой пользователь может получить доступ к каким подкаталогам приложения. Таким образом, соответствующие разделы моего файла web.config выглядят так:
<system.web>
<authentication mode="Forms">
<forms loginUrl="Default.aspx" path="/" protection="All" timeout="360" name="MyAppName" cookieless="UseCookies" />
</authentication>
<authorization >
<allow users="*"/>
</authorization>
</system.web>
<location path="Admin">
<system.web>
<authorization>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
Исходя из того, что я прочитал, это должно гарантировать, что единственными пользователями, которые смогут получить доступ к каталогу администратора, будут пользователи, прошедшие проверку подлинности и которым назначена роль администратора.
Аутентификация пользователя, сохранение билета аутентификации и другие связанные с этим вопросы работают нормально. Если я удаляю теги из файла web.config, все работает нормально. Проблема возникает, когда я пытаюсь обеспечить, чтобы только пользователи с ролью администратора могли иметь доступ к каталогу администратора.
Основываясь на этой статье MS KB , а также на других веб-страницах, содержащих ту же информацию, я добавил следующий код в мой файл Global.asax:
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
if (HttpContext.Current.User != null) {
if (Request.IsAuthenticated == true) {
// Debug#1
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
// In this case, ticket.UserData = "Admin"
string[] roles = new string[1] { ticket.UserData };
FormsIdentity id = new FormsIdentity(ticket);
Context.User = new System.Security.Principal.GenericPrincipal(id, roles);
// Debug#2
}
}
}
Однако, когда я пытаюсь войти в систему, я не могу получить доступ к папке администратора (перенаправляется на страницу входа).
Попытка отладить проблему, если я пошагово выполняю запрос, если я выполняю Context.User.IsInRole ("Admin") в строке с пометкой Debug # 1 выше, она возвращает false. Если я выполню ту же инструкцию в строке Debug # 2, это будет равно true. Так что, по крайней мере, что касается Global.asax, роль назначается правильно.
После Global.asax выполнение переходит прямо на страницу входа в систему (поскольку отсутствие роли приводит к отклонению загрузки страницы в папке администратора). Однако, когда я выполняю ту же инструкцию в первой строке Page_Load логина, он возвращает false. Таким образом, где-то после Application_AuthenticateRequest в Global.asax и начальной загрузки WebForm в ограниченном каталоге, информация о роли теряется, что приводит к сбою аутентификации (примечание: в Page_Load правильный билет аутентификации по-прежнему назначается Context.User.Id - теряется только роль).
Что я делаю не так, и как мне заставить его работать должным образом?
Обновление: я ввел решение ниже