我想保护WCF服务的某些端点,我不知道你是否可以保护某些端点,而不是。下面我有剥离的WCF服务(自托管)。相同的WCF也用于CA Policy文件。如果我保护此WCF服务或某些端点,则CA Policy部分不得向我询问用户名密码。策略文件必须始终可访问。这也可能吗?
我找到了很多WCF自定义博客/帖子。有很多方法可以做到安全。我想要的只是我可以使用用户名/密码保护一些端点,但使用像Fiddler这样的工具不能看到凭据。但是数据在这种情况下可以看到。
我已经实现了一个Customvalidator,但app.config文件也是重要的来定义东西。而且我对此并不擅长。
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public ServiceHost _host = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
_host = new ServiceHost(typeof(WmsStatService));
_host.AddServiceEndpoint(typeof(IPolicyProvider), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
_host.Open();
}
}
// Define a service contract.
[ServiceContract(Namespace = "http://WindowsFormsApplication11")]
public interface IWmsStat
{
[OperationContract]
string getConnectedViewers(string channelName);
[OperationContract]
string sayHello(string name);
}
[ServiceContract]
public interface IPolicyProvider
{
[OperationContract, WebGet(UriTemplate = "/ClientAccessPolicy.xml")]
Stream ProvidePolicy();
}
//[DataContract]
public class Ads
{
// [DataMember]
public string AdFileName { get; set; }
//[DataMember]
public string AdDestenationUrl { get; set; }
public string ConnectedUserIP { get; set; }
}
//
public class CustomValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if(null == userName || null == password)
{
throw new ArgumentNullException();
}
if(userName == "Oguz" && password == "2009")
{
return;
}
FaultCode fc = new FaultCode("ValidationFailed");
FaultReason fr = new FaultReason("Good reason");
throw new FaultException(fr,fc);
}
}
//
public class WmsStatService : IWmsStat, IPolicyProvider
{
public string sayHello(string name)
{
return "hello there " + name + " nice to meet you!";
}
public Stream ProvidePolicy()
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(File.ReadAllBytes("ClientAccessPolicy.xml"), false);
}
public string getConnectedViewers(string channelname)
{
// do stuff
return null;
}
}
}
app.config。此配置文件不起作用。我想为端点进行自定义身份验证。我不知道。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex">
<host>
<baseAddresses>
<add baseAddress="http://192.168.0.199:87" />
</baseAddresses>
</host>
<endpoint address="http://192.168.0.199:87/Test" binding="basicHttpBinding" bindingConfiguration="" contract="WindowsFormsApplication11.IWmsStat" behaviorConfiguration="MyServiceBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!--<bindings>
<wsHttpBinding>
<binding name="wshttp">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>-->
<behaviors>
<serviceBehaviors>
<behavior name="mex">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
<behavior name="MyServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
答案 0 :(得分:17)
我想保护一个端点 WCF服务,我不知道你是否可以 保护一些端点而不是某些端点。
当然 - 你只需要创建两个单独的绑定配置,并在那些受保护的端点上使用一个,另一个在其他端点上使用:
<bindings>
<basicHttpBinding>
<binding name="secured">
<security mode="Message">
<message ...... />
</security>
</binding>
<binding name="unsecured">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex">
<host>
<baseAddresses>
<add baseAddress="http://192.168.0.199:87" />
</baseAddresses>
</host>
<endpoint address="/Secured/Test"
binding="basicHttpBinding" bindingConfiguration="secured"
contract="WindowsFormsApplication11.IWmsStat"
behaviorConfiguration="MyServiceBehavior" />
<endpoint address="/Unsecured/Test"
binding="basicHttpBinding" bindingConfiguration="unsecured"
contract="WindowsFormsApplication11.IWmsStat"
behaviorConfiguration="MyServiceBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
马克
PS:不确定你的帖子不再是最新的问题 - 你注意到,你有两个不同的行为配置:
<behaviors>
<serviceBehaviors>
<behavior name="mex">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
<behavior name="MyServiceBehavior">
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
并且您的服务仅引用“mex”行为?这意味着,您的服务确实使用<serviceMetadata>
行为 - 但不 <serviceCredentials>
行为!
您需要将这些合并为一个然后引用:
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="...." behaviorConfiguration="Default"
马克
答案 1 :(得分:2)
如果要保护整个邮件,可以使用传输安全模式。如果您只想对标题进行加密/签名,则Message安全模式允许这样做,但您必须使用wsHttpBinding。您也可以考虑使用摘要来保护凭据。
至于你的例子,我认为你评论的部分应该是这样的:
<bindings>
<basicHttpBinding>
<binding name="secure">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
您还必须更新您的终端声明:
<endpoint
address="https://192.168.0.199:87/Test"
binding="basicHttpBinding" bindingConfiguration="secure"
contract="WindowsFormsApplication11.IWmsStat" />
您将不被允许使用带传输安全模式的普通HTTP。