当打开基本和/或Windows身份验证并关闭匿名身份验证时,如何让我的控制台应用程序与IIS托管的WCF服务连接?WCF身份验证NT质询响应
该网站是内部和严格的安全性是不需要的。没有域控制器。但是,我需要关闭匿名访问。
我已经搜索了几天,并尝试了很多方法,包括使用自己托管的证书和覆盖认证验证,覆盖UserNameValidator
和使用client.ClientCredentials.Windows.ClientCredentials.UserName
或client.ClientCredentials.UserName.UserName
。这些都没有奏效。
如果有人愿意查看并运行代码,并帮助我使用身份验证运行示例,那么我将处于一个不错的位置。
我冒昧地上传了包含HostWebSite,ClientConsole和API项目的沙盒解决方案。
我主持我的Windows Live SkyDrive中的zip文件:WCF_Authentication.zip
一些小的设置步骤。
我加入到hosts文件
127.0.0.1 hostwebsite.local
我添加了一个网站,IIS
- 位置:HostWebSite project root
,
- 结合:hostwebsite.local
- 应用程序池:Classic 4.0 app pool
。应用安全
Everyone
读取HostWebSite项目目录的访问权限。验证可以看到服务
http://hostwebsite.local/services/EchoService.svc
验证控制台回送的Hello World。
然后通过IIS /身份验证关闭匿名并打开基本和/或Windows身份验证。
谢谢
对于读者的利益,我包括在这里的代码片断
项目:API
namespace API.Contract
{
[ServiceContract]
public interface IEcho
{
[OperationContract]
string SendEcho(string message);
}
}
namespace API.Proxy
{
public class EchoProxy : IEcho
{
public string SendEcho(string message)
{
return string.Concat("You said: ", message);
}
}
}
namespace API.Service
{
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public class EchoService : System.ServiceModel.ClientBase<IEcho>, IEcho
{
public EchoService()
{
}
public EchoService(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public EchoService(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public EchoService(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public EchoService(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public string SendEcho(string message)
{
return base.Channel.SendEcho(message);
}
}
}
项目:ClientConsole
static void Main(string[] args)
{
EchoService client = new EchoService("WSHttpBinding_IEcho");
try
{
Console.WriteLine(client.SendEcho("Hello World"));
client.Close(); // i tried putting this in the finally block but the client would close in an errored state it said.
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
客户端配置
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IEcho" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://hostwebsite.local/Services/EchoService.svc/services/EchoService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEcho"
contract="API.Contract.IEcho" name="WSHttpBinding_IEcho">
<identity>
<servicePrincipalName value="host/mikev-ws" />
</identity>
</endpoint>
</client>
</system.serviceModel>
项目:HostWebSite
<system.serviceModel>
<!-- SERVER -->
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="API.Proxy.EchoProxy" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="/services/EchoService.svc" binding="wsHttpBinding" contract="API.Contract.IEcho" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
@VinayC:你好,谢谢你的帮助。我已经尝试了你的建议。我不得不改变绑定到basicHttpBinding;那是对的吗?我收到的第一个配置更改的错误消息是'该HTTP请求未经授权,客户端身份验证方案'协商'。从服务器收到的验证头是'Basic realm ='hostwebsite.local''。'。其中有配置更改和验证代码的第二个错误消息与我提到的第一个错误消息相同,但“协商”一词由Ntlm替换。谢谢 – 2011-03-29 10:36:57
@Valamas,首次配置改变工作,你必须允许在IIS上进行集成/ Windows认证。在这里,客户端计算机上登录的用户凭证将被提供给服务器 - 如果该用户在服务器上未被识别,则这将不起作用。对于使用基本身份验证方案,您需要将clientCredentialType更改为basic,设置realm值并在代码中设置ClientCredentials.UserName(设置用户和密码)。 – VinayC 2011-03-29 11:19:14
@VinayC:我正在遵循基本认证路径。在IIS中仅启用基本身份验证。我已经跟踪了你的最后一个陈述,包括我已经设定为空的领域。在IIS中,在基本身份验证下,领域和域字段也是空的。 浏览到服务页面返回错误('HTTP:// hostwebsite.local /服务/ EchoService.svc'): '该服务的安全设置需要“匿名”身份验证,但它不为承载IIS应用程序启用此服务.' ....(续) – 2011-03-29 15:56:02