在WCF中,自定义Authentication,Validate方法,抛出错误异常时如何在不停止服务的情况下处理异常?
Posted
技术标签:
【中文标题】在WCF中,自定义Authentication,Validate方法,抛出错误异常时如何在不停止服务的情况下处理异常?【英文标题】:In WCF, custom Authentication, the Validate method, how to handle exception without stopping service when throwing fault exception? 【发布时间】:2020-12-25 00:30:23 【问题描述】:我有一个使用自定义身份验证的 WCF 服务,继承自 UserNamePasswordValidator, 而且,我注意到如果用户未进行身份验证/无效,我必须抛出错误异常才能使身份验证工作。
我的问题是我只想为客户端而不是服务器抛出异常。因为,我不想停止服务器。
我搜索了答案,找到了 FaultContract,但没有用。
这是我的代码
public override void Validate(string userName, string password)
if (HandleAuthentication(userName, password))
// Authenticated
return;
else
throw new FaultException(
"Invalid username or password.",
new FaultCode("AUTHENTICATION_FAILURE"));
【问题讨论】:
【参考方案1】:这是我的演示:
Service.cs:
using System;
using System.IdentityModel.Selectors;
using System.Security.Principal;
using System.ServiceModel;
namespace Microsoft.Samples.UserNamePasswordValidator
// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.Samples.UserNamePasswordValidator")]
public interface ICalculator
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
// Service class which implements the service contract.
// Added code to write output to the console window
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class CalculatorService : ICalculator
public double Add(double n1, double n2)
double result = n1 + n2;
Console.WriteLine("Received Add(0,1)", n1, n2);
Console.WriteLine("Return: 0", result);
return result;
public double Subtract(double n1, double n2)
double result = n1 - n2;
Console.WriteLine("Received Subtract(0,1)", n1, n2);
Console.WriteLine("Return: 0", result);
return result;
public double Multiply(double n1, double n2)
double result = n1 * n2;
Console.WriteLine("Received Multiply(0,1)", n1, n2);
Console.WriteLine("Return: 0", result);
return result;
public double Divide(double n1, double n2)
double result = n1 / n2;
Console.WriteLine("Received Divide(0,1)", n1, n2);
Console.WriteLine("Return: 0", result);
return result;
public class CustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
// This method validates users. It allows in two users, test1 and test2
// with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// MUST NOT be used in a production environment because it is NOT secure.
public override void Validate(string userName, string password)
if (null == userName || null == password)
throw new ArgumentNullException();
if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
throw new FaultException("Unknown Username or Incorrect Password");
// Host the service within this EXE console application.
public static void Main()
// Create a ServiceHost for the CalculatorService type and provide the base address.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("The service is running in the following account: 0", WindowsIdentity.GetCurrent().Name);
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
App.config:
<?xml version="1.0"?>
<!--
Copyright (c) Microsoft Corporation. All rights reserved.
-->
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.UserNamePasswordValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<!-- configure base address for host -->
<add baseAddress="http://localhost:8001/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address provided by host, provide one endpoint -->
<endpoint address="username" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="Microsoft.Samples.UserNamePasswordValidator.ICalculator"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- Username binding -->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior" includeExceptionDetailInFaults="True">
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify a custom validator for username/password combinations.
-->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.Samples.UserNamePasswordValidator.CalculatorService+CustomUserNameValidator, service"/>
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
如果问题仍然存在,请随时告诉我。
这是一个演示:
如果你需要这个例子,你可以在下面的链接中得到它:
https://www.microsoft.com/en-us/download/details.aspx?id=21459
【讨论】:
我尝试创建新的控制台应用程序并重新创建它,但出现错误,例如 ServiceHost 不存在,我需要检查 nuget。我检查了命名空间的 nuget,但结果我已经下载了包。你能给我演示应用程序,看看这是否可行。谢谢。以上是关于在WCF中,自定义Authentication,Validate方法,抛出错误异常时如何在不停止服务的情况下处理异常?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 IIS 中将 WCF 与 basichttpbinding only 、 SSL 和 Basic Authentication 一起使用?
Windows authentication for WCF web services error