我知道标题是满口的。我已经掌握了大部分的东西。如果我能做我正在尝试的事情,我只需要确认。
我正在使用ASP.NET MVC 3.我有一个应用程序,它具有我使用的控制器,就像一个Web服务。控制器上有一个方法,它返回一个字符串,即json。此方法根据活动目录对用户进行身份验证。
对上述应用程序执行WebRequest的应用程序也是MVC应用程序。此应用程序(为了在没有特定用户名和密码的情况下查询AD)正在web.config中使用模拟。该应用程序模拟有权查询AD的帐户;但是,页面上用户的信息(例如他们所在的组)是我验证的。
简而言之(我并不完全理解这一部分),模仿是严格的,因此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;
}
}
那么,如果我通过以下网址直接在浏览器中访问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;
}
}
这准确地传递了主要用户的身份。
答案 0 :(得分:1)
两个想法:
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