我们遇到了这个问题,发现当使用(在我们的情况下是IE)以进程帐户登录的浏览器,然后通过应用程序(SharePoint)更改会话登录时,错误被抛出。 我相信这种情况可以通过两个身份验证方案进行验证:
- 协商
- NTLM
该应用程序托管了一个 *.asmx web 服务,并在负载均衡服务器上调用它,使用类似 WCF 的 .NET3.5 绑定启动了对自身的 web 服务调用。
用于调用 Web 服务的代码:
public class WebServiceClient<T> : IDisposable
{
private readonly T _channel;
private readonly IClientChannel _clientChannel;
public WebServiceClient(string url)
: this(url, null)
{
}
public WebServiceClient(string url,
Action<CustomBinding, HttpTransportBindingElement, EndpointAddress, ChannelFactory> init)
{
var binding = new CustomBinding();
binding.Elements.Add(
new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));
var transport = url.StartsWith("https", StringComparison.InvariantCultureIgnoreCase)
? new HttpsTransportBindingElement()
: new HttpTransportBindingElement();
transport.AuthenticationScheme = System.Net.AuthenticationSchemes.Ntlm;
binding.Elements.Add(transport);
var address = new EndpointAddress(url);
var factory = new ChannelFactory<T>(binding, address);
factory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
if (init != null)
{
init(binding, transport, address, factory);
}
this._clientChannel = (IClientChannel)factory.CreateChannel();
this._channel = (T)this._clientChannel;
}
public T Channel
{
get { return this._channel; }
}
public IClientChannel ClientChannel
{
get { return this._clientChannel; }
}
public void Dispose()
{
this._clientChannel.Dispose();
}
}
我们发现,如果会话凭据与浏览器进程账户相同,则只使用NTLM并且调用成功。否则会导致以下捕获的异常:
“HTTP请求未经授权,客户端认证方案为'Ntlm'。从服务器接收到的身份验证标头是'Negotiate,NTLM'。”
最后,我非常确定其中一个身份验证方案将通过身份验证,而另一个身份验证方案则不会,因为它没有被授予适当的访问权限。