无需客户端证书的 WCF 消息/方法安全性

发布于 2024-10-14 13:29:15 字数 350 浏览 4 评论 0原文

我有一个 WCF 服务,托管在 IIS 中。在服务上,我的服务中有大约20个方法。我想使用用户名/密码保护其中一些方法。我对调用该服务的客户端没有任何控制权,因此无法在客户端上安装证书。我们的服务充当一个平台,保存所有用户个人资料信息,包括登录信息。

我认为我希望客户端对 WCF 服务上的 Authenticate(username,password) 方法进行一次身份验证,获取授权令牌,并将该令牌传递给后续调用。 (有点像 Asp.net 会员提供商使用表单身份验证会话)。如果可能的话,我不希望客户端必须为每个方法调用传递用户名/密码。这是正确的模式吗?有没有更好的方法可以使用标准 WCF 功能来实现此功能?有人有任何示例配置/代码来展示使其工作的正确方法吗?

I have a WCF service, hosted in IIS. On the service, I have about 20 methods in the service. I would like to secure SOME of those methods with username/password. I don't have any control over the clients that are calling the service, so I can't install a certificate on the client. Our services act as a platform, holding all the user profile information, including login information.

I THINK that I would like the clients to authenticate once to the Authenticate(username,password) method on the WCF service, get an authorization token back, and pass that token for subsequent calls. (Sort of like Asp.net membership providers use of forms auth sessions). I don't want the client to have to pass the username/password for every method call, if possible. Is this the right pattern? Is there a better way to get this feature to work using standard WCF functionality? Does anybody have any sample config/code to show the right way to get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

音盲 2024-10-21 13:29:16

WCF 不提供开箱即用的每个操作身份验证。如果您想要安全和不安全的操作,最简单的方法是将它们分为两个服务合同,并使用不同的安全设置公开每个服务合同。

您的授权令牌想法已在 WCF 中实现,但在您的场景中,您必须使用 wsHttpBinding、UserName 客户端凭据、SecurityContext 和服务证书。

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="securedService">
          <serviceCredentials>
            <serviceCertificate x509FindType="FindBySubjectName" findValue="ServerCert" 
                                storeLocation="LocalMachine" storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="Secured">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="MessageSecurity.Service" behaviorConfiguration="securedService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Secured"
                  contract="MessageSecurity.IService">
        </endpoint>
      </service>
    </services>
  </system.serviceModel>

SecurityContext 是基于 WS-SecureConversation 的互操作功能。它只需要在服务代理实例的第一次调用中传递用户名和密码(在 WCF 中这是完全透明的 - 客户端代理实例维护安全上下文)。以下调用仅使用第一次调用期间颁发的安全令牌。 SecurityContext 在 wsHttpBinding 中默认打开。

此配置还将对消息进行加密和签名 - 它是全功能 WS-Security。任何其他方法都取决于您。您必须完全自己实施它。

您提到您无法控制客户。这并不意味着您不能使用证书。如果您使用证书,则客户有责任在想要呼叫您的服务时获取该证书。它与对客户端的控制无关,而是与对证书的信任有关 - 对于公共 Web 服务,这意味着从受信任的证书颁发机构购买证书。

此外,无需安装即可获取服务证书。第一种可能性是使用证书作为端点身份。在这种情况下,编码证书是 WSDL 的一部分:

<wsdl:service name="Service">
  <wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService">
    <soap12:address location="http://localhost:1432/Service.svc" /> 
    <wsa10:EndpointReference>
      <wsa10:Address>http://localhost:1432/Service.svc</wsa10:Address> 
      <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <X509Data>
            <X509Certificate>MIICmzCCAYegAwI....<X509Certificate> 
          </X509Data>
        </KeyInfo>
      </Identity>
    </wsa10:EndpointReference>
  </wsdl:port>
</wsdl:service>

如果您指定配置了服务证书的 wsHttpBinding 端点并且未设置其标识,则会自动完成此操作。此方法的缺点是证书过期。如果您更改过期的证书,则必须更新所有客户端。

第二种可能性是启用服务凭证协商:

<bindings>
  <wsHttpBinding>
    <binding name="Secured">
      <security mode="Message">
        <message clientCredentialType="UserName" negotiateServiceCredential="true"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

默认情况下协商处于打开状态。它使用 TLSNego 协议在安全通信开始之前交换服务凭证(证书)。此方法的缺点是并非所有平台都支持 TLSNego。

WCF does not provide per operation authentication out of the box. If you want secured and unsecured operations the easiest approach is to divide them into two service contracts and expose each with different security settings.

Your idea of authorization token is already implemented in WCF but in your scenario you have to use wsHttpBinding, UserName client credentials, SecurityContext and service certificate.

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="securedService">
          <serviceCredentials>
            <serviceCertificate x509FindType="FindBySubjectName" findValue="ServerCert" 
                                storeLocation="LocalMachine" storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="Secured">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="MessageSecurity.Service" behaviorConfiguration="securedService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Secured"
                  contract="MessageSecurity.IService">
        </endpoint>
      </service>
    </services>
  </system.serviceModel>

SecurityContext is interoperable feature based on WS-SecureConversation. It requires passing user name and password only in first call from service proxy instance (in WCF this is fully transparent - client proxy instance maintains security context). Following calls only use security token issued during first call. SecurityContext is turned on by default in wsHttpBinding.

This configuration will also encrypt and sign messages - it is full power WS-Security. Any other approach is just up to you. You will have to implement it completely by yourselves.

You mentioned that you don't have control over clients. It doesn't mean that you can't use certificate. If you use certificate, it is responsibility of clients to get it if they want to call your service. It has nothing to do with control over clients its about trust to the certificate - for public web service it means buying the certificate from trusted certification authority.

Moreover it is possible to get service certificate without installing it. First possibility is to use certificate as endpoint identity. In such case, encoded certificate is part of WSDL:

<wsdl:service name="Service">
  <wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService">
    <soap12:address location="http://localhost:1432/Service.svc" /> 
    <wsa10:EndpointReference>
      <wsa10:Address>http://localhost:1432/Service.svc</wsa10:Address> 
      <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <X509Data>
            <X509Certificate>MIICmzCCAYegAwI....<X509Certificate> 
          </X509Data>
        </KeyInfo>
      </Identity>
    </wsa10:EndpointReference>
  </wsdl:port>
</wsdl:service>

This is automatically done if you specify wsHttpBinding endpoint with service certificate configured and you do not set its identity. Drawback of this method is that certificate expiration. If you change expired certificate all clients must be updated.

Second possibility is to enable service credentials negotiation:

<bindings>
  <wsHttpBinding>
    <binding name="Secured">
      <security mode="Message">
        <message clientCredentialType="UserName" negotiateServiceCredential="true"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Negotiation is turned on by default. It uses TLSNego protocol to exchange service credentials (certificate) before secure communication starts. Drawback of this method is that TLSNego is not supported by all platforms.

看轻我的陪伴 2024-10-21 13:29:16

仅供参考:如果您想使用内置的 WCF 自定义用户/密码子系统,WCF 4.0 引入了 允许不安全传输属性。这允许您在没有证书的情况下使用 WCF 安全子系统等...这在您认为消息传递是安全的情况下非常有用,即使 WCF 不认为它是安全的(例如当 SSL 在设备级别完成而不是在设备级别完成时) Web 服务器级别,或使用 IP 过滤时)。

FYI: If you want to use the built-in WCF custom user/pass subsystem, WCF 4.0 introduced an Allow Insecure Transport property. This allows you to use the WCF security subsystem without certs etc... This is useful in situations where you consider the messaging to be secured even though WCF doesn't think it is (such as when SSL is done on an appliance level instead of a webserver level, or when IP filtering is used).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文