Webサービス(WCFではなく古いWebサービス)があり、IIS7.0を使用してそのWebサービスと通信しています。IIS 7.0ではWindows認証のみが有効になっています(匿名でも無効になっています)。サービス呼び出しを行うときに、コード内で特定のWindowsIDを指定できる必要があります。私はこれが次の方法で設定ファイルで行うことができることを示す多くの場所を見つけました...
<authentication mode="Windows" />
<identity impersonate="true" userName="UserName" password="P@ssw0rd" />
しかし、私はこれと同じことをコードで行う必要があります。「どうしてそんな風にやりたいのか」と思っている方も多いのではないでしょうか。大きな長い説明に立ち入ることなく、最も簡単な答えは、それらが私の要件だからです。
これが私のコードのようです...
HttpTransportBindingElement transport = useHttps ? new HttpsTransportBindingElement() : new HttpTransportBindingElement();
transport.ManualAddressing = false;
transport.MaxBufferPoolSize = 134217728; // 128MB
transport.MaxReceivedMessageSize = 134217728; // 128MB
transport.AllowCookies = false;
transport.AuthenticationScheme = AuthenticationSchemes.Negotiate;
transport.BypassProxyOnLocal = false;
transport.DecompressionEnabled = true;
transport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
transport.KeepAliveEnabled = true;
transport.MaxBufferSize = 134217728; // 128MB,
transport.ProxyAuthenticationScheme = AuthenticationSchemes.Negotiate;
transport.Realm = "";
transport.TransferMode = TransferMode.Buffered;
transport.UnsafeConnectionNtlmAuthentication = false;
transport.UseDefaultWebProxy = false;
TextMessageEncodingBindingElement encoding = new TextMessageEncodingBindingElement
{
MaxReadPoolSize = 64,
MaxWritePoolSize = 16,
MessageVersion = MessageVersion.Soap12,
WriteEncoding = Encoding.UTF8,
ReaderQuotas = new XmlDictionaryReaderQuotas
{
MaxDepth = 32,
MaxStringContentLength = 134217728, // 128MB
MaxArrayLength = 134217728, // 128MB
MaxBytesPerRead = 4096,
MaxNameTableCharCount = 16384
}
};
CustomBinding binding = new CustomBinding();
binding.Elements.Add(encoding);
binding.Elements.Add(transport);
ServicePointManager.Expect100Continue = false;
generalSoapClient general = new generalSoapClient(binding, new EndpointAddress("http://localhost/site/ws/general.asmx"));
NetworkCredential iisCredentials = new NetworkCredential("UserName", "P@ssw0rd");
general.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
general.ClientCredentials.Windows.ClientCredential = iisCredentials;
string session = general.CreateDomainUserSessionFromInstance();
クライアント側の.configファイルには何も定義されていません。すべてがコードで構成されます。
私のWebサービスメソッドは次のようになります(認証に関係のないコードが欠落しています)...
[WebMethod(EnableSession = true)]
[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
public string CreateDomainUserSessionFromInstance()
{
if(HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
{
WindowsIdentityRequest authenticationRequest = new WindowsIdentityRequest(instanceName, HttpContext.Current.User.Identity as WindowsIdentity);
response = authManager.Login(authenticationRequest);
}
return response.SessionContext.SessionToken;
}
サーバー側の私のweb.configは次のようになります...
<system.web>
<authentication mode="Windows" />
<identity impersonate="true" />
<authorization>
<!--<allow users="*" />-->
<deny users="?" />
</authorization>
</system.web>
<customBinding>
<binding name="textHttpBinding" receiveTimeout="00:05:00" sendTimeout="00:05:00">
<textMessageEncoding>
<readerQuotas maxArrayLength="1024000000" maxStringContentLength="1024000000" />
</textMessageEncoding>
<httpTransport maxReceivedMessageSize="1024000000" maxBufferSize="1024000000" authenticationScheme="Negotiate" />
</customBinding>
<deny users="?" />
次のエラーが発生した場合..." HTTPリクエストはクライアント認証スキーム'Negotiate'で許可されていません。サーバーから受信した認証ヘッダーは''<allow users="*" />
"でした。 Webサービスにアクセスしますが、これHttpContext.Current.User.Identity.IsAuthenticated
は誤りであり、空です。インターネットで読んだことは、匿名アクセスを拒否する.Name
必要があるということです。deny users="?" />
私はWebサービスを初めて使用するため、残念ながら、このコードのほとんどはギリシャ語です。私たちのWebサービスは当初匿名認証を許可していましたが、Windows認証を要求するように要件が変更されました。
私は数日かけて多くのWebサイトを読んで、すべてを正しく構成しようとしましたが、正しい組み合わせが見つからないようです。
私は何が間違っているのですか?それは単純なことですか、それとも私はベースから離れていますか?