仅通过HTTPS的WCF服务
问题描述:
我有一个RESTful WCF服务,我想在Windows Server 2008 R2服务器上托管。它目前作为应用程序托管在现有网站中。一个自签名证书正用于端口443.仅通过HTTPS的WCF服务
我希望服务仅通过HTTPS提供。在应用程序的SSL设置中,我将它设置为“需要SSL”。端点配置如下:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="Rest">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization serviceAuthorizationManagerType="ACME.MyAuthorizationManager, ACME.WS.Authorization" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
然而,试图通过浏览器(例如https://example.com/myservices/baz-service/yip-resource
)来访问该服务时我收到403个响应。
配置过程中我错过任何东西吗?
答
在IIS上设置“需要SSL”选项意味着您正在使用客户端证书执行身份验证。如果您没有任何客户端证书身份验证,只需将该选项设置为忽略或禁用该选项即可。
为了避免您的服务仅在HTTPS上投放,请从您网站上的“绑定”选项中移除HTTP绑定。否则,只需公开您的绑定以将传输用作安全机制,并且应该只处理仅在HTTPS上提供服务的WCF服务。
UPDATE:
请找我如何有IIS上承载的RESTful服务以https:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class RestService
{
// TODO: Implement the collection resource that will contain the SampleItem instances
private static List<SampleItem> sampleCollection = new List<SampleItem>();
[WebGet(UriTemplate = "/get-Collection")]
public List<SampleItem> GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
if (sampleCollection.Count == 0)
{
sampleCollection = new List<SampleItem>();
sampleCollection.Add(new SampleItem() { Id = 1, StringValue = "Hello 1" });
sampleCollection.Add(new SampleItem() { Id = 2, StringValue = "Hello 2" });
sampleCollection.Add(new SampleItem() { Id = 3, StringValue = "Hello 3" });
sampleCollection.Add(new SampleItem() { Id = 4, StringValue = "Hello 4" });
sampleCollection.Add(new SampleItem() { Id = 5, StringValue = "Hello 5" });
}
return sampleCollection;
}
}
我的Global.asax:
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(RestService)));
}
}
我的web.config文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
</diagnostics>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxBufferSize="500000" maxReceivedMessageSize="500000">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="localhost" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
现在我的IIS有HTTPS绑定指定:
现在我的虚拟目录已配置名称XmlRestService,因此当我浏览到资源我得到下面的输出:
答
有很多不同的方式来实现WCF。像许多这样的答案不适合我。我提出了以下快速解决方案。我认为这可能是最普遍和最简单的解决方案。这可能不被认为是雄辩的,但对于我们大多数人来说,无论如何我们的工作都没有得到赞赏。您可以尝试重定向,至少对于GET请求,而不是抛出错误。
#if !DEBUG
// check secure connection, raise error if not secure
IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
if (!request.UriTemplateMatch.BaseUri.AbsoluteUri.StartsWith("https://"))
{
throw new WebProtocolException(HttpStatusCode.BadRequest, "Https is required to use this service.", null);
}
#endif
您是如何访问该服务的?从浏览器或wcf代理? – BNL 2012-02-06 16:49:58
绑定/端点配置对于您的svc是什么样的? – 2012-02-06 16:50:22
初始尝试访问正在通过浏览器完成。我已经添加了端点配置。 – Bullines 2012-02-06 17:33:23