模拟,Active Directory和"用户无权访问xxxx"问题

jas*_*son 5 c# asp.net asp.net-mvc impersonation asp.net-mvc-3

我有2个ASP.NET MVC 3应用程序.我通过web.config使用模拟,以允许我查询Active Directory以获取用户的详细信息.该应用程序使用Windows身份验证,不允许匿名用户.一个应用程序是用户执行其任务的主要应用程序.另一个允许用户在应用程序1中设置其他用户的外观.

测试用户收到以下错误:

SQL1092N  "<DOMAIN ID>" does not have the authority to perform the requested command.
Run Code Online (Sandbox Code Playgroud)

在我从主应用程序向辅助应用程序发送Web请求后,会发生这种情况.为了实现这一点,我必须让请求冒充实际用户而不是模拟应用程序用于模拟的身份.这实际上是我发布并回答的问题.就在这里:如何通过WebRequest调用MVC Action并通过Active Directory验证请求?

在该代码的最后,我打电话给:

impersonationContext.Undo();
Run Code Online (Sandbox Code Playgroud)

在发生此Web请求之后,主应用程序尝试访问数据库,现在似乎上述调用已撤消模拟应用程序,因此用户尝试执行任何打开数据库连接的操作失败.至少,经过一天的抨击之后,这是我的工作理论.

我的问题是,如何模拟应用程序以恢复web.config中的用户?或者,在发出我的Web请求时,是否有办法确保模拟上下文仅适用于该请求?

所有这一切的重点是第二个应用程序有自己的sql server数据库.主应用程序使用DB2.我想编写一次数据库访问代码,但在两个应用程序中都使用它.目前这就是我所做的,但我依靠Web请求获取数据的方法可能不是最好的方法.

我愿意接受任何想法,评论,建议和/或批评.我该怎么办呢?

jas*_*son 1

好吧...我的理论是,在发出 Web 请求时 IPrincipal 上下文已更改,事实证明是准确的,这使得此修复变得非常容易。最好的部分是,我可以继续使用我构建的 API 来发出此请求,而无需重复 Sql Server 实体框架部分。

我对 api 库进行了以下调用:

            proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
                adUserInfo.AssociateId,
                context.User);
Run Code Online (Sandbox Code Playgroud)

此代码由授权过滤器属性调用。方法原型如下

public void OnAuthorization(AuthorizationContext filterContext)     
Run Code Online (Sandbox Code Playgroud)

在内部,该调用使 GetProxies 方法执行以下调用:

        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.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                //request.UseDefaultCredentials = useDefaultCredentials;            
                //IWebProxy p = new WebProxy();
                //request.Proxy = p.
                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;
            }
            finally
            {
                impersonationContext.Undo();
            }

        }
Run Code Online (Sandbox Code Playgroud)

当调用方法返回时,用户的身份不再是应用程序模拟的身份。修复方法非常简单:

            //Track current identity before proxy call
            IPrincipal user = context.User;
            proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
                adUserInfo.AssociateId,
                context.User);

            //Undo any impersonating done in the GetProxies call
            context.User = user;    
Run Code Online (Sandbox Code Playgroud)

2行代码解决了12个小时的头痛。它本来会更糟。无论如何。感谢您成为参谋。我尝试与鸭子进行这种转换,但鸭子感到困惑。