如何通过WebRequest调用MVC操作并通过Active Directoryvalidation请求?

我知道标题是满口的。 我已经掌握了大部分的东西。 我只需要确认我是否可以做我正在尝试的事情。

我正在使用ASP.NET MVC 3.我有一个应用程序,它具有我使用的控制器,就像一个Web服务。 控制器上有一个方法,它返回一个字符串,即json。 此方法根据活动目录对用户进行身份validation。

对上述应用程序执行WebRequest的应用程序也是MVC应用程序。 此应用程序(为了在没有特定用户名和密码的情况下查询AD)正在web.config中使用模拟。 该应用程序模拟有权查询AD的帐户; 但是,页面上用户的信息(例如他们所在的组)是我validation的。

简而言之(我并不完全理解这一部分),模仿是严格的,因此ASP.NET可以查询Active Directory。 当我查询活动目录以获取其信息时,加载页面的用户仍被视为自己。

AD代码如下所示(此代码有效):

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

此应用程序的IIS站点不允许匿名访问。

使用AD信息的服务方法工作正常。 问题似乎是通过WebRequest传递凭据来调用此方法并返回JSON。

我调用该操作的WebRequest代码如下所示:

  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()); } } 

我正在玩ImpersonationLevel ……还没有工作….

通过WebRequest调用的MVC 3操作类似于:

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

那么,如果我通过以下url直接在浏览器中访问MVC 3 Controller / Action会发生什么:

HTTP://:90 / MyApp的/ Service.aspx / CheckForProxy /报表/ 555

我可以在页面上看到正确的JSON。 但是,如果我从同一服务器上的另一个应用程序对此相同的URL进行WebRequest调用,则Active Directory似乎不能轮询它。 这绝对是某种权限问题,但我不确定如何解决它,以便服务查看用户的Active Directory信息。

这里的问题是传递给服务的凭证是调用应用程序模拟的帐户的凭证。 如何更改服务mvc应用程序以查看执行WebRequest的用户(应用程序是否进行调用,但用户是否加载应用程序)而不是应用程序模拟的帐户?

我对处理这种沟通的其他想法或方法持开放态度。

解决方案每个jmrnet评论

哇,那个评论很有意思。 我不知道是什么类型的网络魔术,但我修改了我的网络请求方法:

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

这准确地传递了主要用户的身份。

两个想法:

1)您可以在进行WebRequest调用之前尝试强制模拟。 像这样:

 var impersonationContext = ((WindowsIdentity)User.Identity).Impersonate(); //Make your WebRequest call here... impersonationContext.Undo(); 

2)您可以在WebRequest调用中传递用户,在服务端从AD获取用户身份,然后使用上述代码的变体来模拟它们。

这是一个链接,它更多地讨论了上面使用的模拟代码: http : //msdn.microsoft.com/en-us/library/w070t6ka.aspx