【问题标题】:Securing WCF service endpoint with custom authentication使用自定义身份验证保护 WCF 服务端点
【发布时间】:2010-11-20 16:34:31
【问题描述】:

我想保护 WCF 服务的某些端点,我不知道您是否可以保护某些端点而某些不能。下面我有剥离的 WCF 服务(自托管)。相同的 WCF 还为 CA 策略文件提供服务。如果我保护此 WCF 服务或 ut 的某些端点,CA 策略部分不得询问我用户名密码。策略文件必须始终可访问。也可以吗?

我发现了很多 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>

【问题讨论】:

    标签: wcf authentication endpoint


    【解决方案1】:

    我想保护某个端点的安全 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”行为?这意味着,您的服务确实在使用 &lt;serviceMetadata&gt; 行为 - 但NOT &lt;serviceCredentials&gt; 一个!

    您需要将它们合并为一个,然后仅引用它:

    <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" 
    

    马克

    【讨论】:

    • 该死我现在得到这个:(无法加载文件或程序集“CustomValidator”或其依赖项之一。系统找不到指定的文件。
    • 该错误来自这里的配置: 当您使用“CustomValidator”程序集时是否可用运行你的服务??
    • 我将其更改为 WindowsFormsAppiication11。这是 Windows 窗体上的自托管 WCF 服务。在我将其更改为我所说的错误之后,错误消失了,但另一个问题:( '192.168.0.199:87/Test' 的 ChannelDispatcher 与合同 '"IWmsStat"' 无法打开其 IChannelListener
    • 如果您使用我的配置,您现在有两个地址:http://192.168.0.199:97/Secured/Test 用于安全服务,http://192.168.0.199:97/Unsecured/Test 用于非安全服务
    • 同意 - 我也是 +1,感谢您的极大耐心和乐于助人的意愿!
    【解决方案2】:

    如果您想保护整个邮件,传输安全模式是一种方法。如果您只想对标头进行加密/签名,消息安全模式允许这样做,但您必须使用 wsHttpBinding。您也可以考虑使用 Digest 来保护凭据。

    至于你的例子,我认为你的评论部分应该是这样的:

    <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。

    【讨论】:

    • 使用该配置我收到以下错误。没有名为“MyServiceBehavior”的端点行为
    • 我不想使用 https 所以我选择了消息安全模式
    • 将 behaviorConfiguration="CalculatorServiceBehavior"> 移至服务标签
    • 在服务标签上有 behaviorConfiguration="mex" 如果我​​更改它会影响我的其余代码吗?
    • 把这两个行为合二为一,参考一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多