如何启用会话使用SSL的wsHttpBinding在WCF [英] How to enable Session with SSL wsHttpBinding in WCF

查看:228
本文介绍了如何启用会话使用SSL的wsHttpBinding在WCF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF服务与wsHttpBindings和启用SSL,但我想启用WCF会话。

I have a WCF Service with wsHttpBindings and SSL enabled, but I'd like to enable WCF sessions.

在改变SessionMode所需

After changing SessionMode to required

SessionMode:=SessionMode.Required

我收到如下所述的错误。

 I'm getting error described below. 

合同需要会话,但绑定WsHttpBinding的不支持   它或者未正确配置来支持它。

Contract requires Session, but Binding 'WSHttpBinding' doesn't support it or isn't configured properly to support it.

下面是我的示例应用程序。

Here's my sample application.

的App.config

  <?xml version="1.0" encoding="utf-8" ?>
    <configuration>

      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- When deploying the service library project, the content of the config file must be added to the host's 
      app.config file. System.Configuration does not support config files for libraries. -->
      <system.serviceModel>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
        <client />
        <bindings>
          <wsHttpBinding>
            <binding name="NewBinding0" useDefaultWebProxy="false" allowCookies="true">
              <readerQuotas maxStringContentLength="10240" />
              <!--reliableSession enabled="true" /-->
              <security mode="Transport">
                <transport clientCredentialType="None" proxyCredentialType="None" >
                  <extendedProtectionPolicy policyEnforcement="Never" />
                </transport >
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <services>
          <service name="WcfServiceLib.TestService">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0"
              contract="WcfServiceLib.ITestService">
              <identity>
                <servicePrincipalName value="Local Network" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="https://test/TestService.svc" />
              </baseAddresses>
            </host>
          </service>
        </services>

        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, 
              set the value below to false and remove the metadata endpoint above before deployment -->
              <serviceMetadata 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>
      </system.serviceModel>

    </configuration>

ITestService.vb

  <ServiceContract(SessionMode:=SessionMode.Required)>
    Public Interface ITestService

        <OperationContract(IsInitiating:=True, IsTerminating:=False)> _
        Function GetData(ByVal value As Integer) As String

    End Interface

TestService.vb

    <ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession, _ 
    ReleaseServiceInstanceOnTransactionComplete:=False, _ 
    ConcurrencyMode:=ConcurrencyMode.Single)>
        Public Class TestService
            Implements ITestService

            Private _user As User

            <OperationBehavior(TransactionScopeRequired:=True)>
            Public Function GetData(ByVal value As Integer) As String _
 Implements ITestService.GetData

                If _user Is Nothing Then

                    _user = New User()
                    _user.userName = "User_" & value
                    _user.userPassword = "Pass_" & value

                    Return String.Format("You've entered: {0} , Username = {1} , Password = {2} ", _
                                         value, _user.userName, _user.userPassword)
                Else
                    Return String.Format("Username = {1} , Password = {2} ", _
                                    _user.userName, _user.userPassword)
                End If

            End Function

        End Class

我尝试了所有可能的解决方案,我能找到,但没有任何帮助。

I tried all possible solutions, I could find, but nothing helped.

一些建议,以使的可靠的会话的,但它不会是 SSL (只要你有你的自定义绑定),其他人的意见,使用 HTTP工作而不是 HTTPS ,但我想,以使会话我目前的配置,如果可能的话。

Some advice to enable reliable sessions, but it doesn't work with ssl (if only you have your custom binding), others advice to use http instead of https, but I'd like to enable Sessions with my current configurations, if it's possible.

有没有实现这一目标的任何做法?

Is there any approach to achieve this?

任何形式的帮助是非常AP preciated。

Any kind of help is much appreciated.

推荐答案

如果你想会与的wsHttpBinding,你必须使用任何可靠的消息,或安全会话。 (来源:<一href="http://stackoverflow.com/questions/2650738/how-to-enable-wcf-session-with-wshttpbidning-with-transport-only-security">how使WCF会议与wsHttpBidning与交通运输仅安全)。

If you want "sessions" with wsHttpBinding, you have to use either reliable messaging, or the security sessions. (source : how to enable WCF Session with wsHttpBidning with Transport only Security).

WsHttpBinding的支持会话,但仅在某个安全(安全会话),或可靠的消息传递启用。 如果您使用的是交通运输的安全性则未使用WS-SecureConversation的和WS-ReliableMessaging的是默认关闭的。因此这WsHttpBinding的使用会话两种协议都没有。您可能需要使用邮件安全或打开可靠的会话。 (来源:<一href="http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/57b3453e-e7e8-4875-ba23-3be4fff080ea/">http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/57b3453e-e7e8-4875-ba23-3be4fff080ea/).

WSHttpBinding supports session but only if either security (SecureConversation) or reliable messaging are enabled. If you are using transport security then it is not using WS-SecureConversation and WS-ReliableMessaging is turned off by default. Therefore the two protocols that WSHttpBinding uses for session are not available. You either need to use message security or turn on reliable session. (source : http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/57b3453e-e7e8-4875-ba23-3be4fff080ea/).

我们已经不允许RM通过HTTPS在标准绑定,因为固定的RM会话的方式是使用一个安全会话和HTTPS不提供会话。

We’ve disallowed RM over Https in the standard bindings because the way to secure an RM session is to use a security session and Https does not provide session.

我发现在MSDN Blurb的关于它的:<一href="http://msdn2.microsoft.com/en-us/library/ms733136.aspx">http://msdn2.microsoft.com/en-us/library/ms733136.aspx Blurb的是使用HTTPS时,唯一的例外是。 SSL会话没有绑定到可靠的会话。这个规定是因为会话共享一个安全上下文(SSL会话)不保护彼此的威胁;这可能是也可能不是根据应用一个真正的威胁。

I found the msdn blurb about it here: http://msdn2.microsoft.com/en-us/library/ms733136.aspx The blurb is "The only exception is when using HTTPS. The SSL session is not bound to the reliable session. This imposes a threat because sessions sharing a security context (the SSL session) are not protected from each other; this might or might not be a real threat depending on the application."

不过,你可以做到这一点,如果你确定没有威胁。有通过自定义的RM通过HTTPS样品结合<一href="http://msdn2.microsoft.com/en-us/library/ms735116.aspx">http://msdn2.microsoft.com/en-us/library/ms735116.aspx (来源:<一href="http://social.msdn.microsoft.com/forums/en-US/wcf/thread/fb4e5e31-e9b0-4c24-856d-1c464bd0039c/">http://social.msdn.microsoft.com/forums/en-US/wcf/thread/fb4e5e31-e9b0-4c24-856d-1c464bd0039c/).

However you can do it if you determine there is no threat. There is an RM over HTTPS sample via custom binding http://msdn2.microsoft.com/en-us/library/ms735116.aspx (source : http://social.msdn.microsoft.com/forums/en-US/wcf/thread/fb4e5e31-e9b0-4c24-856d-1c464bd0039c/).

要总结一下您的可能性,您可以:

To sum up your possibilities you can either :

1 - 保持的wsHttpBinding,除去运输安全,实现可靠的消息

1 - Keep wsHttpBinding, remove transport security and enable reliable messaging

  <wsHttpBinding>
    <binding name="bindingConfig">
      <reliableSession enabled="true" />
      <security mode="None"/>
    </binding>
  </wsHttpBinding>

但你失去了SSL层,然后安全的一部分。

But you loose the SSL layer and then part of your security.

2 - 保持的wsHttpBinding,保持运输安全,并添加消息认证

2 - Keep wsHttpBinding, keep transport security and add message authentication

  <wsHttpBinding>
    <binding name="bindingConfig">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </wsHttpBinding>

您能留住你的SSL安全层,但你的客户一定要提供凭证(任何形式),即使你没有在服务端对其进行验证,假的还必须提供为WCF将拒绝任何消息不指定凭据。

You get to keep your SSL security layer but your client will have to provide credentials (of any form) and even if you don't validate them at the service side, fake ones must still be provided as WCF will reject any message not specifying credentials.

3 - 使用自定义与可靠的消息传递和HTTPS传输绑定

3 - Use a custom binding with reliable messaging and HTTPS transport

  <customBinding>
    <binding name="bindingConfig">
      <reliableSession/>
      <httpsTransport/>
    </binding>
  </customBinding>

我看不到任何缺点这种除了MSDN中解释了威胁,这取决于你的应用程序。

I can't see any downside to this except the threat explained in MSDN, and it depends on your application.

4 - 使用其他会议提供商 如果您的应用程序hotsed在IIS中,您可以设置

4 - Use other session providers If your application is hotsed in IIS, you could set

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

和依赖

HttpContext.Current.Session

你的状态。

或实现你自己的cookie。

Or implementing your own cookies.

PS:需要注意的是,所有这些WCF配置,我只测试服务激活,没有电话

PS : Note that for all those WCF configuration, I only tested service activation, not calls.

编辑:由于每个用户的请求,的wsHttpBinding TransportWithMessageCredential 安全模式执行会议(我不是太熟悉用VB.NET所以原谅我的语法):

EDIT : As per user request, wsHttpBinding with TransportWithMessageCredential security mode implementing sessions (I'm not too familiar with VB.NET so pardon my syntax) :

服务code片断:

<ServiceContract(SessionMode:=SessionMode.Required)>
Public Interface IService1

    <OperationContract()> _
    Sub SetSessionValue(ByVal value As Integer)

    <OperationContract()> _
    Function GetSessionValue() As Nullable(Of Integer)

End Interface

<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession, 
    ConcurrencyMode:=ConcurrencyMode.Single)>
Public Class Service1
    Implements IService1

    Private _sessionValue As Nullable(Of Integer)

    Public Sub SetSessionValue(ByVal value As Integer) Implements IService1.SetSessionValue
        _sessionValue = value
    End Sub

    Public Function GetSessionValue() As Nullable(Of Integer) Implements IService1.GetSessionValue
        Return _sessionValue
    End Function
End Class

Public Class MyUserNamePasswordValidator
    Inherits System.IdentityModel.Selectors.UserNamePasswordValidator

    Public Overrides Sub Validate(userName As String, password As String)
        ' Credential validation logic
        Return ' Accept anything
    End Sub

End Class

服务配置片段:

service Configuration snippet :

<system.serviceModel>
  <services>
    <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
      <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" bindingConfiguration="bindingConf"/>
      <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
    </service>
  </services>
  <bindings>
    <wsHttpBinding>
      <binding name="bindingConf">
        <security mode="TransportWithMessageCredential">
          <message clientCredentialType="UserName"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="WcfService1.Service1Behavior">
        <serviceMetadata httpsGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="false"/>
        <serviceCredentials>
          <userNameAuthentication 
            userNamePasswordValidationMode="Custom"
            customUserNamePasswordValidatorType="WcfService1.MyUserNamePasswordValidator, WcfService1"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

客户端测试code片断:

Client test code snippet :

Imports System.Threading.Tasks

Module Module1

    Sub Main()
        Parallel.For(0, 10, Sub(i) Test(i))
        Console.ReadLine()
    End Sub

    Sub Test(ByVal i As Integer)
        Dim client As ServiceReference1.Service1Client
        client = New ServiceReference1.Service1Client()
        client.ClientCredentials.UserName.UserName = "login"
        client.ClientCredentials.UserName.Password = "password"
        Console.WriteLine("Session N° {0} : Value set to {0}", i)
        client.SetSessionValue(i)
        Dim response As Nullable(Of Integer)
        response = client.GetSessionValue()
        Console.WriteLine("Session N° {0} : Value returned : {0}", response)
        client.Close()
    End Sub

End Module

这篇关于如何启用会话使用SSL的wsHttpBinding在WCF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆