Я пытаюсь сделать что-то немного хакерское - но такое чувство, что это может быть выполнимо.
По существу, у меня есть приложение ASP.Next, которое использует аутентификацию Windows.
В некоторых сценарияхЯ хочу, чтобы привилегированные (администраторские) пользователи могли «подделывать» разных пользователей (использовать разные имена и назначать себе меньше ролей приложений). Информация о пользователе и роли для подделки передаются в HTTP-заголовках по запросу.
Я хотел, чтобы приложение сначала использовало Windows для проверки подлинности того, что исходный пользователь является администратором (и, таким образом, ему разрешено обманывать других пользователей). А затем установите для свойства пользователя HTTP-контекста общий принципал (созданный на основе информации из запроса), чтобы следующий код по существу не обращал внимания на спуфинг.
Я поместил код, который изменяет пользователя, вSystem.Web.IHttpModule
(см. Код ниже).
При использовании других режимов аутентификации (например, форм) работает следующий код;но с аутентификацией Windows, хотя все выглядит хорошо в отладчике (я вижу, что код выполняется и запрос был аутентифицирован) к моменту вызова EndRequest, ответ на запрос всегда заканчивается как 401. (Если я закомментирую строку, котораяУстанавливает пользователя, тогда все нормально).
То, что я хотел бы знать, это;где код, который устанавливает код ответа 401? И можно ли этого избежать / отключить? То, что я пытаюсь сделать, просто невозможно?
Большое спасибо
using System;
using System.Security.Principal;
using System.Web;
using System.Net;
namespace ACME
{
public sealed class SpoofModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.AuthenticateRequest += ScrapeFlowedUser;
context.EndRequest += HandleEndRequest;
context.AuthorizeRequest += ScrapeFlowedUser;
}
public void HandleEndRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
// Always end up here if I set HttpContext.Current.User to any other user.
}
}
private void ScrapeFlowedUser(object sender, EventArgs e)
{
var userIdentity = HttpContext.Current.User?.Identity;
if (userIdentity.IsAuthenticated && userIdentity.Name == "ACME\\Admin")
{
HttpContext.Current.User = CreateUserFromDataOnRequest();
}
}
private GenericPrincipal CreateUserFromDataOnRequest()
{
string userName = "JoeBlogs"; // the name and roles will be passed in the request headers.
string[] roles = new[] { "Role1", "Role2" };
var id = new GenericIdentity(userName);
return new GenericPrincipal(id, roles); // The generic principal has IsAuthenticated == true.
}
public void Dispose()
{
}
}
}
Web config
<modules>
<add name="Spoof" type="ACME.SpoofModule, ACME.App" />
</modules>