Como faço para chamar uma ação do MVC por meio de um WebRequest e validar a solicitação por meio do Active Directory?

Eu sei que o título é um bocado. Eu já tenho mais coisas no lugar. Eu só preciso de confirmação se posso fazer o que estou tentando.

Eu estou usando o asp.net MVC 3. Eu tenho um aplicativo que tem o controlador que eu uso como um serviço da web. Existe um único método no controlador e retorna uma string, que é json. Este método autentica o usuário no diretório ativo.

O aplicativo que executa um WebRequest para o acima é também um aplicativo MVC. Este aplicativo (para consultar o AD sem um nome de usuário e senha específicos) está usando a representação no web.config. O aplicativo representa uma conta que tem permissão para consultar o AD; no entanto, as informações do usuário na página (como em quais grupos eles estão) são contra as quais eu valido.

Em suma (e não entendo totalmente essa parte), a representação é estritamente para que o ASP.NET possa consultar o Active Directory. Os usuários que carregam a página ainda são vistos como eles mesmos quando eu consultar o diretório ativo para obter informações.

O código do AD se parece com o seguinte (este código funciona):

   public static ADUserInfo GetUserInfo(IPrincipal User)
    {
        StringBuilder userAdInfo = new StringBuilder();
        ADUserInfo userInfo = new ADUserInfo();
        String domain = ConfigurationManager.AppSettings["ADdomain"];

        try
        {
            using (var context = new PrincipalContext(ContextType.Domain, domain))
            {
                if (User == null)
                    userAdInfo.AppendLine("User is null.");
                else if (User.Identity == null)
                    userAdInfo.AppendLine(" User is not null. User.Identitiy is.");
                else
                    userAdInfo.AppendLine(" Neither User nor User.Identity is null. " +
                        User.Identity.Name);

                using (var user = UserPrincipal.FindByIdentity(context, User.Identity.Name))
                {
                    userInfo.FullName = user.Name;
                    userInfo.Email = user.EmailAddress;
                    userInfo.AssociateId = user.EmployeeId;
                    userInfo.DomainName = User.Identity.Name;
                    userInfo.SamAccountName = user.SamAccountName;
                    userInfo.DistinguishedUserName = user.DistinguishedName;
               }
            }
        }
        catch (Exception e)
        {
            LogUtil.WriteException(e);
        }
        return userInfo;
    }

O site do IIS para este aplicativo não permite acesso anônimo.

O método de serviço que usa informações do AD funciona bem. O problema parece estar passando credenciais por meio de um WebRequest para chamar esse método e obter o JSON retornado.

Meu código WebRequest para chamar a ação é semelhante:

    public class WebRequestUtil
    {
        public static StreamReader GetWebRequestStream(
             string url,
             string contentType,
             bool useDefaultCredentials)
        {
            var request = WebRequest.Create(url);
            request.ContentType = contentType;
            request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            //request.UseDefaultCredentials = useDefaultCredentials;
            //ICredentials ic = new NetworkCredential();

            //request.Credentials = 
            var response = (HttpWebResponse)request.GetResponse();
            return new StreamReader(response.GetResponseStream());
        }
    }

Estou jogando com o ImpersonationLevel ... ainda não funcionou ....

A ação do MVC 3 sendo chamada via WebRequest é algo como:

public class ProxyServiceController : Controller
    {

        public ProxyServiceController()
        {

        }

       public string CheckForProxy(string applicationName, string associateId)
        {
            RequestResultDetails requestDetails = new RequestResultDetails();
            string json = string.Empty;

            //This correctly gets the Active directory information for the user
            //and fills out a custom ADUserInfo object.
            **ADUserInfo adUserInfo = ADService.GetUserInfo(this.User);**

            try
            {

                if (!ADService.DoesUrlDataMatchAD(
                                adUserInfo,
                                associateId)
                    )
                {
                    throw new Exception(StaticText.UserDataMismatch);
                }

                resultList = //query db for data given the associateId

                if (resultList.ListIsNotNullOrEmpty())
                {
                    requestDetails.RelationshipExists = true;
                }
                else
                {
                    requestDetails.RelationshipExists = false;
                }

                requestDetails.Details = resultList;

            }
            catch (Exception e)
            {
                LogUtil.WriteException(e);
                requestDetails.ErrorProcessingRequest = true;
                requestDetails.ErrorDetails = ErrorProcessing.GetFullExceptionDetails(e);
            }

            json = JsonConvert.SerializeObject(requestDetails);

            LogUtil.Write("json: " + json);

            return json;

        }
}       

Então, o que acontece é que, se eu vou para o MVC 3 Controller / Action diretamente no navegador através de uma URL como:

http: //: 90 / MyApp / Service.aspx / CheckForProxy / Reporting / 555

Eu posso ver o JSON correto na página. No entanto, se eu fizer uma chamada do WebRequest para esse mesmo URL a partir de outro aplicativo que esteja no mesmo servidor, o Active Directory não parecerá que possa ser pesquisado. Este é definitivamente algum tipo de problema de permissões, mas não tenho certeza de como resolvê-lo para que o serviço veja as informações do Active Directory do usuário.

O problema aqui é que as credenciais que estão sendo passadas para o serviço são aquelas da conta que o aplicativo chamador está representando. O que eu mudo para obter o aplicativo mvc de serviço para ver o usuário executando o WebRequest (bem, o aplicativo faz a chamada, mas o usuário carrega o aplicativo) e não a conta que o aplicativo está representando?

Estou aberto a outros pensamentos ou métodos para lidar com essa comunicação.

SOLUÇÃO POR jmrnet COMENTÁRIO

Uau, esse comentário foi no local. Não tenho ideia de que tipo de magia da Web está sendo trabalhada, mas revisei meu método de solicitação da Web para:

  public static StreamReader GetWebRequestStream(
         string url,
         string contentType,
         bool useDefaultCredentials,
         IPrincipal user)
    {

        var impersonationContext = ((WindowsIdentity)user.Identity).Impersonate();            
        var request = WebRequest.Create(url);

        try
        {
            request.ContentType = contentType;
            request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
            request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            var response = (HttpWebResponse)request.GetResponse();
            return new StreamReader(response.GetResponseStream());
        }
        catch (Exception e)
        {
            impersonationContext.Undo();
            throw e;
        }

    }

E isso passa com precisão a identidade do usuário principal.

questionAnswers(1)

yourAnswerToTheQuestion