5

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

测试用户收到以下错误:

SQL1092N  "<DOMAIN ID>" does not have the authority to perform the requested command.

这发生在我从主要应用程序向辅助应用程序发送 Web 请求之后。为了让它工作,我必须让请求模拟实际用户,而不是应用程序用于模拟的身份。这实际上是我发布并回答的一个 SO 问题。就在这里:如何通过 WebRequest 调用 MVC 操作并通过 Active Directory 验证请求?

在该代码的末尾,我调用:

impersonationContext.Undo();

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

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

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

我愿意接受任何想法、评论、建议和/或批评。我应该如何处理这个?

4

1 回答 1

1

好的……我的理论是,当提出 Web 请求时 IPrincipal 上下文发生了变化,这证明是准确的,这使得这个修复变得非常容易。最好的部分是,我可以继续使用我构建的 api 来发出这个请求,而无需复制 Sql Server 实体框架部分。

我对我的 api 库有以下调用:

            proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
                adUserInfo.AssociateId,
                context.User);

此代码由授权过滤器属性调用。方法原型看起来像

public void OnAuthorization(AuthorizationContext filterContext)     

在内部,调用会在调用之后生成 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();
            }

        }

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

            //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;    

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

于 2013-02-01T19:32:04.083 回答