Preview 6 HTTPS Only

Topics: Web Api
Feb 2, 2012 at 7:21 PM

I'm having frustrating problems figuring out how to configure WebApi for HTTPS binding only.

Security = (uri, security) =>
{
    if (uri.Scheme.Equals("https"StringComparison.InvariantCultureIgnoreCase))
        security.Mode = HttpBindingSecurityMode.Transport;
    else
        security.Mode = HttpBindingSecurityMode.TransportCredentialOnly;
 
    security.Transport.ClientCredentialType = HttpClientCredentialType.None;
}

This doesn't work. I can still access my services via HTTP. I also don't want HttpClientCredentialType.Basic since I'm using my own custom authentication scheme.
Feb 2, 2012 at 7:22 PM
Edited Feb 2, 2012 at 7:23 PM

*deleted by user*

Sorry I thought you wanted to enforce HTTPS, the title is misleading. You're trying to use WS security.

Feb 2, 2012 at 8:30 PM
Edited Feb 2, 2012 at 8:34 PM

No, you were correct .. I am just looking to simply enforce HTTPS.  I have custom authentication/authorization operation handlers, but do not want to allow HTTP traffic.

So is that simply what should be done? Just make a DelegatingHandler or OperationHandler that cuts off the request?  Can't we simply specify BaseHostPrefixes?

Is this definitive behavior going forward with WebApi?

Feb 2, 2012 at 8:40 PM

    public class RequireSSLRequestHandler : HttpOperationHandler<HttpRequestMessage, HttpRequestMessage>
    {
        public RequireSSLRequestHandler()
            : base("request")
        {
        }

        protected RequireSSLRequestHandler(string outputParameterName)
            : base(outputParameterName)
        {
            
        }

        protected override HttpRequestMessage OnHandle(HttpRequestMessage input)
        {
            if (input.RequestUri.Scheme != "https")
            {
                var challengeMessage = new HttpResponseMessage(HttpStatusCode.Forbidden);
                throw new HttpResponseException(challengeMessage);
            }

            return input;
        }
    }

Feb 2, 2012 at 10:42 PM

I think this requirement is best solved outside of your Web API implementation.  If you have access to IIS configuration, you can simply disable the HTTP binding.  If not, you can employ URL rewriting to redirect all HTTP requests to HTTPS.  See http://forums.iis.net/t/1149780.aspx for an example.

Feb 2, 2012 at 10:44 PM
Edited Feb 2, 2012 at 10:45 PM

I agree with davidpeden3. We have the same requirement, only SSL, but we require NON-SSL when developing. That's why I used a handler. We just disable the handler in dev.

Feb 2, 2012 at 11:53 PM
digitalpacman wrote:

I agree with davidpeden3. We have the same requirement, only SSL, but we require NON-SSL when developing. That's why I used a handler. We just disable the handler in dev.


I personally use the URL rewrite technique and have the rewrite rule disabled in my development web.config.  I just use a web.config transform to enable the rewrite rule for production deployment.  Works perfectly and I don't have to edit and remember to unedit my code.  ;)

Feb 2, 2012 at 11:53 PM

#if DEBUG is not edit/unedit code ;/

Feb 2, 2012 at 11:56 PM

I would definitely agree with this position as well, however, my services are being hosted in an MVC Web Application which must allow HTTP traffic, but redirect to HTTPS.

I think for now I'll have to use either Url Re-writing or a DelegatingHandler unless there is a way to customize the service host.

Feb 3, 2012 at 12:00 AM

If you're running it side by side with another UI, it would be better to refuse all SSL requests. You shouldn't redirect the requests, because the content bodys will be lost anyway. I'd throw a StatusCode.Forbidden when someone hits the API without SSL. Then use normal 301 redirects for the normal site, and exclude the API from your redirects.

Feb 3, 2012 at 12:06 AM

I should have clarified that. The redirect is solely for the web application.  Thanks for your input guys.

Feb 3, 2012 at 12:06 AM

Goodluck! You should go solve some of my issues while you're at it ;)