Azure 中的 WCF 安全和身份验证 (WsHttpBinding, 使用用户名和密码凭据)






4.33/5 (2投票s)
如何通过 HTTPS 在 Azure Web 应用中配置 WCF 服务,并进行身份验证,只需几个简单的步骤。
引言
我花费了大量时间研究和调查 Azure 中的 WCF 安全性,但找不到直接在 Azure Web 应用中实现的有效解决方案。有很多关于 WCF 安全性的内容涉及 IIS、Azure 云服务(webrole/webworker),但没有关于 Azure Web 应用程序(或 Web API)的内容。因此,以下是在 Azure Web 应用中设置 HTTPS 和基本身份验证的一些简单步骤,这些步骤对我有效。
操作指南
我们需要处理线路的两端:WCF 服务本身及其客户端
服务
如你可能已经知道,HTTPS 协议需要 SSL 证书。好消息是,Azure *.azurewebsites.net 域名已经由 Microsoft 提供的证书保护。你可以使用 https://mywebsite.azurewebsites.net 安全地访问你的站点。但是,请注意,*.azurewebsites.net 是一个共享域名,与所有共享域名一样,不如使用你自己的证书的自定义域名安全。在 Azure 应用服务中为应用启用 HTTPS 和自定义域名超出了本文的主题范围,你可以在以下资源中找到有用的信息 https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure-ssl-certificate/
Web.config
首先,让我们设置服务器的 web.config
<system.serviceModel> <services> <service name="MyProject.MyService" behaviorConfiguration="serviceBehavior"> <endpoint address="https://mywebapi.azurewebsites.net/MyService.svc" binding="wsHttpBinding" bindingConfiguration="secureHttpBinding" contract="MyProject.Service.Contracts.IMyService" /> </service> </services> <behaviors xdt:Transform="Replace"> <serviceBehaviors> <behavior name="serviceBehavior"> <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> <serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.ClientAuthenticator, MyNamespace" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="secureHttpBinding" hostNameComparisonMode="StrongWildcard" receiveTimeout="00:01:00" sendTimeout="00:01:00" openTimeout="00:01:00" closeTimeout="00:01:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="524288" messageEncoding="Text" textEncoding="utf-8" bypassProxyOnLocal="false" useDefaultWebProxy="true" > <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName" /> </security> </binding> </wsHttpBinding> </bindings> </system.serviceModel>
这里有一些值得强调的元素
- Endpoint 运行在 HTTPS 上(
address="https://mywebapi.azurewebsites.net/MyService.svc"
) - WsHttpBinding endpoint 绑定配置具有
<security>
标签,其中mode="TransportWithMessageCredential"
和clientCredentialType="UserName"
因此,服务将期望请求中的客户端凭据。因此,我们启用了 WCF 基本身份验证。 - ServiceBehavior 通过 ServiceCredentials 进行设置,通过这种方式我们告诉 WCF 使用什么方法来验证客户端的凭据。在我们的例子中,是下面描述的
MyNamespace.ClientAuthenticator.cs
类。
ClientAuthenticator.cs
其次,我们需要一个身份验证器来验证客户端
using System; using System.Collections.Generic; using System.Configuration; using System.IdentityModel.Selectors; using System.Linq; using System.ServiceModel; using System.Web; namespace MyNamespace { public class ClientAuthenticator: UserNamePasswordValidator { public override void Validate(string userName, string password) { if (null == userName || null == password) { throw new FaultException("Credential arguments are not supplied"); } var appSettings = ConfigurationManager.AppSettings; if (!string.Equals(userName, appSettings["basicAuthUser"], StringComparison.OrdinalIgnoreCase) && !string.Equals(password, appSettings["basicAuthPsw"], StringComparison.Ordinal)) { throw new FaultException("Invalid user and/or password"); } } } }
客户端
Web.config
<system.serviceModel> <client> <endpoint address="https://mywebapi.azurewebsites.net/MyService.svc" binding="wsHttpBinding" bindingConfiguration="secureHttpBinding" contract="MyProject.Client.Contracts.IMyService" /> </client> <bindings> <wsHttpBinding> <binding name="secureHttpBinding" hostNameComparisonMode="StrongWildcard" receiveTimeout="00:01:00" sendTimeout="00:01:00" openTimeout="00:01:00" closeTimeout="00:01:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="524288" messageEncoding="Text" textEncoding="utf-8" bypassProxyOnLocal="false" useDefaultWebProxy="true" > <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName" /> </security> </binding> </wsHttpBinding> </bindings> </system.serviceModel>
请注意,无法在 web.config 文件的 <system.serviceModel>
标签中配置客户端凭据,我们需要在代码中进行设置。
提供客户端凭据
PeopleServiceClient client = new PeopleServiceClient(); var appSettings = ConfigurationManager.AppSettings; client.ClientCredentials.UserName.UserName = appSettings["basicAuthUser"]; client.ClientCredentials.UserName.Password = appSettings["basicAuthPsw"];
结论
就这样,一切就绪,Azure 中的 WCF Web 应用已安全。请记住,客户端也必须通过 HTTPS 运行,才能以正确的方式与 WCF 通信。希望这篇文章能为你节省大量研究这个主题的时间。祝你编程愉快。
历史
- 2016 年 4 月 16 日:初始版本。