如何使用用户名/密码 + SSL 使用 WCF 配置安全的 RESTful 服务

问题描述:

我希望编写一个允许在 WCF 中使用 RESTful 服务的配置文件,但我仍然希望能够利用"成员资格提供程序进行用户名/密码身份验证.

I'm looking to write a config file that allows for RESTful services in WCF, but I still want the ability to 'tap into' the membership provider for username/password authentication.

以下是我当前配置的一部分,使用 basicHttp 绑定或 wsHttp w/out WS Security,这将如何更改 w/基于 REST 的服务?

The below is part of my current config using basicHttp binding or wsHttp w/out WS Security, how will this change w/ REST based services?

    <bindings>
        <wsHttpBinding>
            <binding name="wsHttp">
                <security mode="TransportWithMessageCredential">
                    <transport/>
                    <message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="false"/>
                </security>
            </binding>
        </wsHttpBinding>
        <basicHttpBinding>
            <binding name="basicHttp">
                <security mode="TransportWithMessageCredential">
                    <transport/>
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="NorthwindBehavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/>
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>

UPDATE 01/23/2012

自从我写了这个问题以来,我看到了一种更好的方法来保护 REST 类的 Web 服务.我第一次听说它时听起来很复杂,但它的想法很简单,并且遍布整个网络,适用于网络服务和其他安全通信.

Since I wrote this question I've seen a much better approach to securing REST like web services in the wild. It sounded complex when I first heard about it but the idea is simple and all over the web for both web services and other secure communication.

它需要使用公钥/私钥.

It requires the use of public/private keys.

1.) 端点的每个用户(客户)都需要注册您的 REST Web 服务

1.) each user (customer) of the endpoint will need to register with your REST web service

  • a.) 你给这个用户一个不应该与他共享的私钥任何人
  • b.) 你还生成了一个可以通过网络传输的公钥如果需要,可以使用纯文本(这也将用于识别客户端)

2.) 来自用户的每个请求都需要生成一个哈希值来对请求进行签名

2.) each request from the user needs to generate a hash to sign the request

  • a.) 其中一个示例可能如下所示:私钥 + 时间戳 + 编码的有效负载(如果足够小,例如要更新的简单用户信息)
  • b.) 你使用这 3 个(或任何你决定的)并生成一个单向哈希(例如使用 hmac)
  • c.) 在通过线路发送的请求中包含公钥(因此服务器端知道谁在尝试发送此请求)、使用私钥生成的哈希值和时间戳.

3.) 服务器端点(您的 REST 方法)将需要使用客户端上使用的相同输入生成哈希.此步骤将证明客户端和服务器都知道与随请求传递的公钥匹配的私钥.(这反过来意味着发送请求的用户是合法的,因为其他人无法知道私钥)

3.) the server endpoint (your REST method) will need to generate a hash using the same inputs used on the client. This step will prove that both client and server knew a private key that matched the public key passed along with the request. (this in turn means that the user sending the request is legit as no one else could know the private key)

  • a.) 通过请求期间传递的公钥查找客户私钥

  • a.) lookup the customers private key by the public key being passed along during the request

b.) 将其他参数(时间戳和编码的有效载荷)与您在上一步中找到的私钥一起使用,并使用相同的算法生成单向哈希(同样,hmac 是我所用的在现实世界中使用过)

b.) take the other params (timestamp and the encoded payload) along with the private key you found in the previous step and use the same algorithm to generate a 1 way hash (again hmac is what I've seen used in the real world)