C# WCF身份验证-使用自定义验证器的用户名密码-在我的机器上工作
我有一个WCF服务和一个客户端,它使用自定义的C# WCF身份验证-使用自定义验证器的用户名密码-在我的机器上工作,c#,wcf,C#,Wcf,我有一个WCF服务和一个客户端,它使用自定义的UserNamePasswordValidator进行身份验证 我使用由以下命令行创建的自签名证书: makecert -sr LocalMachine -ss My -a sha1 -n CN=SelfSignedCertificate -sky exchange -pe 从以下客户端调用服务中的方法在我的计算机上可以正常工作:),但一旦我将其部署到服务器上,就会收到以下错误消息:由于身份验证失败,无法满足对安全令牌的请求。 我可以浏览端点URL
UserNamePasswordValidator
进行身份验证
我使用由以下命令行创建的自签名证书:
makecert -sr LocalMachine -ss My -a sha1 -n CN=SelfSignedCertificate -sky exchange -pe
从以下客户端调用服务中的方法在我的计算机上可以正常工作:),但一旦我将其部署到服务器上,就会收到以下错误消息:由于身份验证失败,无法满足对安全令牌的请求。
我可以浏览端点URL并查看服务的WSDL。我不确定,但我记得我在本地机器上的IIS中配置了一些匿名身份验证,但在服务器上看起来也类似
我的WCF服务托管在IIS 7.0中,使用以下配置:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="secured">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
<binding name="unsecured">
<security mode="None" />
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="secured">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
<binding name="unsecured">
<security mode="None" />
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="unsecured">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="Milkshake.Admin.Services.AdminService" behaviorConfiguration="CustomValidator">
<endpoint address="" binding="wsHttpBinding" contract="Milkshake.Admin.Model.ServiceContracts.IAdminService" bindingConfiguration="secured" />
</service>
<service name="Milkshake.Admin.Services.DeploymentService">
<endpoint address="" binding="wsHttpBinding" contract="Milkshake.Admin.Model.ServiceContracts.IDeploymentService"/>
</service>
<service name="Milkshake.Admin.Services.LogService" behaviorConfiguration="CustomValidator">
<endpoint address="" binding="wsHttpBinding" contract="Milkshake.Core.Logging.ILogService" bindingConfiguration="secured" />
</service>
<service name="Milkshake.Admin.Services.MailService">
<endpoint address="" binding="wsHttpBinding" contract="Milkshake.Admin.Model.ServiceContracts.IMailService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CustomValidator">
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<serviceCertificate findValue="SelfSignedCertificate" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Milkshake.Admin.Services.MilkshakeCredentialValidator, Milkshake.Admin.Services" />
<clientCertificate>
<authentication certificateValidationMode="None" />
</clientCertificate>
</serviceCredentials>
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="json">
<enableWebScript />
</behavior>
<behavior name="xml">
<webHttp defaultOutgoingResponseFormat="Xml" defaultBodyStyle="Wrapped" />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
客户端配置如下所示:
<system.serviceModel>
<client>
<endpoint address="http://server-url/LogService.svc" binding="wsHttpBinding" contract="Milkshake.Core.Logging.ILogService">
<identity>
<dns value="SelfSignedCertificate" />
</identity>
</endpoint>
</client>
</system.serviceModel>
using System;
using System.ServiceModel;
using System.ServiceModel.Security;
using Milkshake.Core.Logging;
namespace Milkshake.Admin.ServiceClients.Logging
{
/// <summary>
/// WCF Service Client implementation of the <see cref="ILogService"/> contract.
/// </summary>
public class LogServiceClient : ILogService
{
/// <summary>
/// Initializes a new instance of the <see cref="LogServiceClient"/> class.
/// </summary>
public LogServiceClient()
{
var factory = new ChannelFactory<ILogService>(String.Empty);
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.Credentials.UserName.UserName = "martin";
factory.Credentials.UserName.Password = "normark";
var binding = factory.Endpoint.Binding as WSHttpBinding;
if (binding != null)
{
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
}
this.AdminLogService = factory.CreateChannel();
}
/// <summary>
/// Gets or sets the admin log service.
/// </summary>
/// <value>The admin log service.</value>
private ILogService AdminLogService { get; set; }
#region ILogService Members
/// <summary>
/// Logs the error simple.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="logDate">The log date.</param>
/// <param name="exceptionMessage">The exception message.</param>
/// <param name="description">The description.</param>
/// <param name="severity">The severity.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="source">The source.</param>
public void LogErrorSimple(int applicationInstanceId, DateTime logDate, string exceptionMessage, string description, Severity severity, string userAgent, string source)
{
this.AdminLogService.LogErrorSimple(applicationInstanceId, logDate, exceptionMessage, description, severity, userAgent, source);
}
/// <summary>
/// Logs the error advanced.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="logDate">The log date.</param>
/// <param name="exceptionType">Type of the exception.</param>
/// <param name="exceptionCode">The exception code.</param>
/// <param name="exceptionMessage">The exception message.</param>
/// <param name="stackTrace">The stack trace.</param>
/// <param name="caller">The caller.</param>
/// <param name="location">The location.</param>
/// <param name="source">The source (A service, app etc).</param>
/// <param name="description">The description.</param>
/// <param name="severity">The severity.</param>
/// <param name="username">The username.</param>
/// <param name="userAgent">The user agent.</param>
public void LogErrorAdvanced(int applicationInstanceId, DateTime logDate, string exceptionType, string exceptionCode, string exceptionMessage, string stackTrace, string caller, string location, string source, string description, Severity severity, string username, string userAgent)
{
this.AdminLogService.LogErrorAdvanced(applicationInstanceId, logDate, exceptionType, exceptionCode, exceptionMessage, stackTrace, caller, location, source, description, severity, userAgent, userAgent);
}
/// <summary>
/// Logs the behavior with data.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="action">The action.</param>
/// <param name="logDate">The log date.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="behaviorData">The behavior data.</param>
/// <param name="source">The source.</param>
public void LogBehaviorWithData(int applicationInstanceId, string action, DateTime logDate, string userAgent, string behaviorData, string source)
{
this.AdminLogService.LogBehaviorWithData(applicationInstanceId, action, logDate, userAgent, behaviorData, source);
}
/// <summary>
/// Logs the behavior.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="action">The action.</param>
/// <param name="logDate">The log date.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="source">The source.</param>
public void LogBehavior(int applicationInstanceId, string action, DateTime logDate, string userAgent, string source)
{
this.AdminLogService.LogBehavior(applicationInstanceId, action, logDate, userAgent, source);
}
#endregion
}
}
我的自定义验证器是:
using System;
using System.IdentityModel.Selectors;
using System.ServiceModel;
namespace Milkshake.Admin.Services
{
/// <summary>
/// WCF Service validator for Milkshake.
/// </summary>
public class MilkshakeCredentialValidator : UserNamePasswordValidator
{
/// <summary>
/// When overridden in a derived class, validates the specified username and password.
/// </summary>
/// <param name="userName">The username to validate.</param>
/// <param name="password">The password to validate.</param>
public override void Validate(string userName, string password)
{
if (String.IsNullOrWhiteSpace(userName) || String.IsNullOrWhiteSpace(password))
{
throw new ArgumentNullException();
}
if (userName.Equals("martin") && password.Equals("normark"))
{
return;
}
FaultCode fc = new FaultCode("ValidationFailed");
FaultReason fr = new FaultReason("Good reason");
throw new FaultException(fr, fc);
}
}
}
使用系统;
使用System.IdentityModel.Selectors;
使用System.ServiceModel;
命名空间Milkshake.Admin.Services
{
///
///奶昔的WCF服务验证程序。
///
公共类MilkshakeCredentialValidator:UserNamePasswordValidator
{
///
///在派生类中重写时,验证指定的用户名和密码。
///
///要验证的用户名。
///要验证的密码。
公共覆盖无效验证(字符串用户名、字符串密码)
{
if(String.IsNullOrWhiteSpace(用户名)| | String.IsNullOrWhiteSpace(密码))
{
抛出新ArgumentNullException();
}
if(userName.Equals(“martin”)&password.Equals(“normark”))
{
返回;
}
FaultCode fc=新的故障代码(“ValidationFailed”);
FaultReason fr=新的FaultReason(“好理由”);
抛出新的FaultException(fr、fc);
}
}
}
我的服务客户端,如下所示:
<system.serviceModel>
<client>
<endpoint address="http://server-url/LogService.svc" binding="wsHttpBinding" contract="Milkshake.Core.Logging.ILogService">
<identity>
<dns value="SelfSignedCertificate" />
</identity>
</endpoint>
</client>
</system.serviceModel>
using System;
using System.ServiceModel;
using System.ServiceModel.Security;
using Milkshake.Core.Logging;
namespace Milkshake.Admin.ServiceClients.Logging
{
/// <summary>
/// WCF Service Client implementation of the <see cref="ILogService"/> contract.
/// </summary>
public class LogServiceClient : ILogService
{
/// <summary>
/// Initializes a new instance of the <see cref="LogServiceClient"/> class.
/// </summary>
public LogServiceClient()
{
var factory = new ChannelFactory<ILogService>(String.Empty);
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.Credentials.UserName.UserName = "martin";
factory.Credentials.UserName.Password = "normark";
var binding = factory.Endpoint.Binding as WSHttpBinding;
if (binding != null)
{
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
}
this.AdminLogService = factory.CreateChannel();
}
/// <summary>
/// Gets or sets the admin log service.
/// </summary>
/// <value>The admin log service.</value>
private ILogService AdminLogService { get; set; }
#region ILogService Members
/// <summary>
/// Logs the error simple.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="logDate">The log date.</param>
/// <param name="exceptionMessage">The exception message.</param>
/// <param name="description">The description.</param>
/// <param name="severity">The severity.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="source">The source.</param>
public void LogErrorSimple(int applicationInstanceId, DateTime logDate, string exceptionMessage, string description, Severity severity, string userAgent, string source)
{
this.AdminLogService.LogErrorSimple(applicationInstanceId, logDate, exceptionMessage, description, severity, userAgent, source);
}
/// <summary>
/// Logs the error advanced.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="logDate">The log date.</param>
/// <param name="exceptionType">Type of the exception.</param>
/// <param name="exceptionCode">The exception code.</param>
/// <param name="exceptionMessage">The exception message.</param>
/// <param name="stackTrace">The stack trace.</param>
/// <param name="caller">The caller.</param>
/// <param name="location">The location.</param>
/// <param name="source">The source (A service, app etc).</param>
/// <param name="description">The description.</param>
/// <param name="severity">The severity.</param>
/// <param name="username">The username.</param>
/// <param name="userAgent">The user agent.</param>
public void LogErrorAdvanced(int applicationInstanceId, DateTime logDate, string exceptionType, string exceptionCode, string exceptionMessage, string stackTrace, string caller, string location, string source, string description, Severity severity, string username, string userAgent)
{
this.AdminLogService.LogErrorAdvanced(applicationInstanceId, logDate, exceptionType, exceptionCode, exceptionMessage, stackTrace, caller, location, source, description, severity, userAgent, userAgent);
}
/// <summary>
/// Logs the behavior with data.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="action">The action.</param>
/// <param name="logDate">The log date.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="behaviorData">The behavior data.</param>
/// <param name="source">The source.</param>
public void LogBehaviorWithData(int applicationInstanceId, string action, DateTime logDate, string userAgent, string behaviorData, string source)
{
this.AdminLogService.LogBehaviorWithData(applicationInstanceId, action, logDate, userAgent, behaviorData, source);
}
/// <summary>
/// Logs the behavior.
/// </summary>
/// <param name="applicationInstanceId">The application instance id.</param>
/// <param name="action">The action.</param>
/// <param name="logDate">The log date.</param>
/// <param name="userAgent">The user agent.</param>
/// <param name="source">The source.</param>
public void LogBehavior(int applicationInstanceId, string action, DateTime logDate, string userAgent, string source)
{
this.AdminLogService.LogBehavior(applicationInstanceId, action, logDate, userAgent, source);
}
#endregion
}
}
使用系统;
使用System.ServiceModel;
使用System.ServiceModel.Security;
使用Milkshake.Core.Logging;
命名空间Milkshake.Admin.ServiceClients.Logging
{
///
///WCF服务客户端合同的实现。
///
公共类LogServiceClient:ILogService
{
///
///初始化类的新实例。
///
公共日志服务客户端()
{
var factory=新的ChannelFactory(String.Empty);
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode=X509CertificateValidationMode.None;
factory.Credentials.UserName.UserName=“martin”;
factory.Credentials.UserName.Password=“normark”;
var binding=factory.Endpoint.binding作为WSHttpBinding;
if(绑定!=null)
{
binding.Security.Mode=SecurityMode.Message;
binding.Security.Message.ClientCredentialType=MessageCredentialType.UserName;
}
this.AdminLogService=factory.CreateChannel();
}
///
///获取或设置管理日志服务。
///
///管理日志服务。
私有ILogService AdminLogService{get;set;}
#区域ILogService成员
///
///简单地记录错误。
///
///应用程序实例id。
///日志日期。
///异常消息。
///描述。
///严重性。
///用户代理。
///消息来源。
public void LogErrorSimple(int applicationInstanceId、DateTime logDate、字符串例外消息、字符串描述、严重性、字符串用户代理、字符串源)
{
this.AdminLogService.LogErrorSimple(applicationInstanceId、logDate、exceptionMessage、描述、严重性、userAgent、源);
}
///
///记录高级错误。
///
///应用程序实例id。
///日志日期。
///异常的类型。
///异常代码。
///异常消息。
///堆栈跟踪。
///打电话的人。
///地点。
///来源(服务、应用程序等)。
///描述。
///严重性。
///用户名。
///用户代理。
public void LogErrorAdvanced(int applicationInstanceId、DateTime logDate、string exceptionType、string exceptionCode、string exceptionMessage、string stackTrace、string调用者、字符串位置、字符串源、字符串描述、严重性、字符串用户名、字符串用户代理)
{
this.AdminLogService.LogErrorAdvanced(applicationInstanceId、logDate、exceptionType、exceptionCode、exceptionMessage、stackTrace、调用者、位置、源、描述、严重性、userAgent、userAgent);
}
///
///使用数据记录行为。
///
///应用程序实例id。
///行动。
///日志日期。
///用户代理。