タイトルは一口です。私はすでにほとんどのものを用意しています。自分がやろうとしていることができるかどうかを確認する必要があります。
ASP.NET MVC3を使用しています。Webサービスのように使用するコントローラーを備えたアプリケーションが1つあります。コントローラには単一のメソッドがあり、jsonという文字列を返します。このメソッドは、ActiveDirectoryに対してユーザーを認証します。
上記のWebRequestを実行するアプリケーションもMVCアプリケーションです。このアプリケーション(特定のユーザー名とパスワードなしでADを照会するため)は、web.configで偽装を使用しています。アプリケーションは、ADを照会する権限を持つアカウントになりすます。ただし、ページ上のユーザーの情報(ユーザーがどのグループに属しているかなど)は、私が検証するものです。
要するに(そして私はこの部分を完全には理解していません)、偽装は厳密に行われているため、ASP.NETはActiveDirectoryにクエリを実行できます。ページをロードしているユーザーは、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情報を使用するサービス方法は正常に機能します。問題は、このメソッドを呼び出してJSONを返すためにWebRequestを介してクレデンシャルを渡すことであるようです。
アクションを呼び出すための私の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を介して呼び出されるMVC3アクションは、次のようになります。
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を使用して、ブラウザーでMVC3コントローラー/アクションに直接アクセスするとどうなりますか。
http://:90 / MyApp / Service.aspx / CheckForProxy / Reporting / 555
ページに正しいJSONが表示されます。ただし、同じサーバー上にある別のアプリケーションからこの同じURLにWebRequest呼び出しを行うと、ActiveDirectoryをポーリングできないように見えます。これは確かにある種のアクセス許可の問題ですが、サービスがユーザーのActiveDirectory情報を参照できるように解決する方法がわかりません。
ここでの問題は、サービスに渡される資格情報が、呼び出し元のアプリケーションが偽装しているアカウントの資格情報であるということです。アプリケーションが偽装しているアカウントではなく、WebRequestを実行しているユーザー(アプリは呼び出しを行いますが、ユーザーはアプリをロードします)を確認するために、サービスMVCアプリケーションを取得するにはどうすればよいですか?
私は、このコミュニケーションを処理するための他の考えや方法を受け入れています。
jmrnetコメントごとのソリューション
うわー、そのコメントはスポットでした。どのようなWebマジックが機能しているかはわかりませんが、Webリクエストの方法を次のように変更しました。
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;
}
}
そして、これは主要なユーザーのIDを正確に伝えます。