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

Posted

技术标签:

【中文标题】如何使用用户名/密码 + SSL 使用 WCF 配置安全 RESTful 服务【英文标题】:How to configure secure RESTful services with WCF using username/password + SSL 【发布时间】:2010-09-13 13:52:56 【问题描述】:

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

以下是我当前使用 basicHttp 绑定或不带 WS 安全性的 wsHttp 配置的一部分,如果使用基于 REST 的服务,这将如何改变?

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

【问题讨论】:

我认为这是一个相关的问题,我希望看到更多关于这个主题的答案,因为我目前正在寻找同样的东西。 REST 是一种风格和设计选择,不应该无法应对身份验证。 【参考方案1】:

这是一个关于使用 ASP.net 成员提供程序保护 WCF REST 服务的播客:

http://channel9.msdn.com/posts/rojacobs/endpointtv-Securing-RESTful-services-with-ASPNET-Membership/

【讨论】:

【参考方案2】:

我同意 Darrel 的观点,即基于 WCF 的复杂 REST 场景是个坏主意。就是不好看。

不过,Dominick Baier 在他的最低权限博客上对此有一些 good posts。

如果您想查看 WSSE 身份验证支持并回退到 WCF 上的 FormsAuthenticationTicket 支持,请查看source code of BlogService。

【讨论】:

【参考方案3】:

在继续沿着这条通过 WCF 实施 REST 的道路之前,我建议您阅读 Tim Ewald 的 this 帖子。我尤其受到以下陈述的影响:

我不确定我想建立在 旨在将 HTTP 考虑在内的层 被设计为的层的顶部 把它排除在外。

在过去的 12 个月里,我一直在使用 WCF 开发基于 REST 的东西,而这句话一次又一次地证明了自己的正确性。恕我直言,WCF 带来的好处远远超过它为进行 REST 工作引入的复杂性。

【讨论】:

我很高兴知道我不是唯一注意到这一点的人! WCF 有很多好处,但是 REST 支持给我带来了不小的麻烦。 WCF 是否设计为将 HTTP 排除在外? HTTP 只是传输选项之一。 没错。 HTTP 是分布式应用程序的协议。 WCF 旨在让您以与协议无关的方式构建分发应用程序。 @pc1oad1etter HTTP 不是传输协议。 HTTP 代表超文本传输​​协议。【参考方案4】:

无论社区是否对 WCF 上的 REST 有意见 (我个人持反对态度) 微软对此进行了抨击,http://msdn.microsoft.com/en-us/netframework/cc950529.aspx

【讨论】:

【参考方案5】:

是的,与 Moto 一致,WCF Starter Kit 的链接是我看到的最接近使用自定义 HTTP 标头 (http://msdn.microsoft.com/en-us/library/dd203052.aspx) 进行凭据身份验证的方法。

但是我无法让示例运行。

【讨论】:

【参考方案6】:

试试custombasicauth @ codeplex

【讨论】:

【参考方案7】:

2012 年 1 月 23 日更新

自从我写了这个问题以来,我已经看到了一种更好的方法来保护 REST,比如在野外的 Web 服务。当我第一次听说它时,它听起来很复杂,但这个想法很简单,并且在整个网络上都适用于网络服务和其他安全通信。

它需要使用公钥/私钥。

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

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

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

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

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

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

b.) 获取其他参数(时间戳和编码的有效负载)以及您在上一步中找到的私钥,并使用相同的算法生成 1 路哈希(再次,hmac 是我已经在现实世界中使用)

c.) 生成的 1 路哈希需要匹配通过网络发送的哈希,如果不发回 400(或您认为是“错误请求”的任何 http 代码)

【讨论】:

以上是关于如何使用用户名/密码 + SSL 使用 WCF 配置安全 RESTful 服务的主要内容,如果未能解决你的问题,请参考以下文章

WCF 消息安全证书

Windows Phone 7 应用程序 + WCF + SSL + 用户名认证

WCF 身份验证

用户密码错误 (WCF):在 web.config 中未正确配置用户密码

如何在 WSDL 中使用 HTTPS 为卸载 SSL 后的 WCF 服务配置服务端点

如何在 IIS 中将 WCF 与 basichttpbinding only 、 SSL 和 Basic Authentication 一起使用?