我有一個Web服務(舊的Web服務,而不是WCF),我使用IIS 7.0與該Web服務進行通信。在IIS 7.0中只啓用Windows身份驗證(甚至禁用匿名)。我需要能夠在進行服務調用時在代碼中指定特定的Windows身份。我發現許多地方,表明這可以在配置文件中以下列方式完成...以編程方式爲Web服務模擬固定的Windows標識
<authentication mode="Windows" />
<identity impersonate="true" userName="UserName" password="[email protected]" />
但我需要在代碼中做同樣的事情。我相信很多人都在想「你爲什麼要這麼做」。不用長篇大論,最簡單的答案是因爲這些都是我的要求。
這裏是我的代碼看起來像......
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", "[email protected]");
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="*" />
,但是當我這樣做時,我可以進入網絡服務,但HttpContext.Current.User.Identity.IsAuthenticated
是虛假的,.Name
是空的,我在互聯網上讀到的是它需要deny users="?" />
來拒絕匿名訪問。
我是新來的Web服務,所以不幸的是這段代碼大部分是希臘語給我。我們的Web服務最初允許匿名身份驗證,但需求已更改爲需要Windows身份驗證。
我花了好幾天的時間閱讀了大量的網站,試圖正確配置一切,並且似乎找不到合適的組合。
我在做什麼錯?這是簡單的事情還是我離開基地?
原來的IIS身份驗證爲主要的網站是該網站的一個子文件夾不同的,那麼。 Web服務位於子文件夾中,我正在查看主站點IIS身份驗證。子文件夾仍然打開了Anonymous。 **花了兩天的時間,我幾乎把自己從窗外扔出去了! –