【发布时间】:2014-10-24 12:59:09
【问题描述】:
我做了一个非常简单的 WCF 应用程序,发现了一个我无法解决的问题。关于 WCF 服务,如果启用了匿名身份验证,它实际上正在工作,但是当我在 IIS 上禁用此功能时,它给了我一个错误:HTTP 请求未经客户端身份验证方案“匿名”授权。从服务器收到的身份验证标头是 ''
这是 web.config 配置:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WCFTestApplication.WCFTestApplication">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WCFTestAppBinding"
contract="WCFTestApplication.IWCFTestApplication"
/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding messageEncoding="Text" name="WCFTestAppBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Windows"/>
<transport clientCredentialType="Windows" proxyCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="false"/>
</system.webServer>
这是客户端应用程序源:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Net;
namespace WCFClientApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string _name = "";
private string _passwd = "";
private string _domain = "";
public string UserName
{
get { return _name; }
set { _name = value; }
}
public string Password
{
get { return _passwd; }
set { _passwd = value; }
}
public string Domain
{
get { return _domain; }
set { _domain = value; }
}
private void button1_Click(object sender, EventArgs e)
{
//if (!String.IsNullOrEmpty(usrTxt.Text) || !String.IsNullOrEmpty(passTxt.Text) || !String.IsNullOrEmpty(domainTxt.Text))
//{
UserName = usrTxt.Text;
Password = passTxt.Text;
Domain = domainTxt.Text;
WCFClientProxy.WCFTestApplicationClient client = new WCFClientProxy.WCFTestApplicationClient();
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(UserName, Password, Domain);
//System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; };
textBox1.Text = client.GetData();
//}
//else
//{
// MessageBox.Show("Fields like username, password and domain must not be blank...!","Warning...!",MessageBoxButtons.OK, MessageBoxIcon.Warning);
//}
}
private void domainTxt_MouseHover(object sender, EventArgs e)
{
tipLbl.Visible = true;
}
private void domainTxt_MouseLeave(object sender, EventArgs e)
{
tipLbl.Visible = false;
}
}
}
wcf 接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFTestApplication
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IWCFTestApplication
{
[OperationContract]
string GetData();
// TODO: Add your service operations here
}
}
类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFTestApplication
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class WCFTestApplication : IWCFTestApplication
{
public string GetData()
{
return "WCF is working, and message is authenticated and encrypted";
}
}
}
我在某处读到匿名身份验证与 MEX 端点和通信有关,但我如何才能保留 Windows 登录,并禁用匿名用户登录,以便在没有适当凭据的情况下无法使用 WCF?
【问题讨论】:
-
为什么要启用表单验证?此外,根据配置,您使用了“Windows”身份验证,并且它不存在于 IIS 中。
-
嗨,需要解释一下吗?我在配置文件中设置了 Windows 身份验证,但您不需要为客户端凭据提供用户名、密码和域吗?
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(UserName, Password, Domain); -
你是对的。在 IIS 身份验证中不显示“Windows 身份验证”。您必须通过进入“启用或禁用功能”来安装该协议。
-
您可以测试的另一件事是“尝试不使用 https”。
-
你尝试过这样的事情吗? msdn.microsoft.com/en-us/library/ff648505.aspx