ASP.Net: возможно ли использовать проверку подлинности Windows и установить для HttpContext.Current.User значение GenericPrincipal - PullRequest
1 голос
/ 01 ноября 2019

Я пытаюсь сделать что-то немного хакерское - но такое чувство, что это может быть выполнимо.

По существу, у меня есть приложение 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>
...