42

I'm creating Self-hosted Web API service. To secure it, I've studied and implemented this article, successfully generated an local SSL Certificate using makecert and my service authenticated and generates tokens fine, if I'm using

http://localhost/webapi/authentication/authenticate

link, but when I try to access my service using HTTPS, I get following on Firefox:

ssl_error_rx_record_too_long

and for the same request Fiddler shows me:

HTTP/1.1 502 Fiddler - Connection Failed Date: Mon, 26 Aug 2013 10:44:27 GMT Content-Type: text/html; charset=UTF-8 Connection: close Timestamp: 13:44:27.433

[Fiddler] The socket connection to localhost failed.
Failed to negotiate HTTPS connection with server.fiddler.network.https> Failed to secure existing connection for localhost. The handshake failed due to an unexpected packet format..

My self-host configuration:

    private HttpSelfHostServer _server;
    private ExtendedHttpsSelfHostConfiguration _config;
    public const string ServiceAddress = "https://localhost/webapi";
    _config = new ExtendedHttpsSelfHostConfiguration(ServiceAddress);
    _server = new HttpSelfHostServer(_config);
    _server.OpenAsync();

where ExtendedHttpSelfHostConfiguration taken from this post is:

public class ExtendedHttpSelfHostConfiguration : HttpSelfHostConfiguration
{
    public ExtendedHttpSelfHostConfiguration(string baseAddress) : base(baseAddress) { }
    public ExtendedHttpSelfHostConfiguration(Uri baseAddress) : base(baseAddress) { }

    protected override BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding)
    {
        if (BaseAddress.ToString().ToLower().Contains("https://"))
        {
            httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
        }

        return base.OnConfigureBinding(httpBinding);
    }
}

What I'm missing? Thanks in advance!

2
  • The link to the post in your question doesn't look right: pfelix.wordpress.com/2012/02/26/… Commented May 3, 2017 at 15:01
  • 1
    A bit more clean check for https: BaseAddress.Scheme == "https" Commented Jan 11, 2019 at 16:02

3 Answers 3

41

According to this blog post I've figured out, that I should create an SSL certificate and assign it to specific port (:99 in my case).

I've created locally signed SSL. Then got it's Thumbprint and ApplicationId. Using CMD command netsh (in pre Win7 systems there is an httpcfg tool), I've assigned my certificate to the port

netsh http add sslcert ipport=0.0.0.0:99 certhash=3e49906c01a774c888231e5092077d3d855a6861 appid={2d6059b2-cccb-4a83-ae08-8ce209c2c5c1}, where certhash = SSL Thumbprint, and appid = ApplicationId I've copied earlier.

That's it, now I'm able to make HTTPS requests!

Sign up to request clarification or add additional context in comments.

1 Comment

You've got a good question here, and a useful answer, but its value depends almost entirely on a link to an external resource. You may want to edit your answer, and add a list of steps specific to Web API that you took to get this working. This would enhance the value of your answer to others in case the hyperlink "rots".
15
  1. Open IIS
  2. Double Click "Server Certificates"
  3. On the right pane, click "Create Self-Signed Certificate"
  4. Enter name "localhost"
  5. Finish

The certificate will be created with the name you specified, find it.

  1. Double click the cert, it will open its properties, select 'Thumbprint' and copy the value.

Now you have created the cert, it is time to bind it to the port you are using in the self host. if it was https://localhost:5000

  1. Open elevated CMD
  2. Run this command to bind the certificate you created to the port you are using.

netsh http add sslcert ipport=0.0.0.0:5000 certhash=[cert-thumbprint] appid={[App-Id]}

  1. Replace the [Cert-thumbprint] (including the square brackets) with the value you copied in step 6.
  2. Replace the [app-id] (including the square brackets) is the guid from the app assembly info

[assembly: Guid("[app-id]")]

You are done!

5 Comments

I think this should be marked as the answer.Explains everything step by step.Than you @Mahmoud
This should not be marked as the answer as the question is about self-hosting, not hosting using IIS. However, this is a great answer for others who might end up on this page looking for a solution related to IIS.
@karezza I think the instructions are saying use IIS only to generate the certificate. Now how do I install IIS...
from where can I get the app-id?
How do you get the Guid of the Web API project (.NET 6)? Tried searching everywhere without success...
-2

First approach using Code:

public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
        {
            actionContext.Response = actionContext.Request
                .CreateResponse(HttpStatusCode.Found);
            actionContext.Response.Content = new StringContent
                ("<did>Use https instead of http</div>", Encoding.UTF8, "text/html");

            UriBuilder uriBuilder = new UriBuilder(actionContext.Request.RequestUri);
            uriBuilder.Scheme = Uri.UriSchemeHttps;
            uriBuilder.Port = 44337;

            actionContext.Response.Headers.Location = uriBuilder.Uri;
        }
        else
        {
            base.OnAuthorization(actionContext);
        }
    }
}

In the web config file put following code:

config.Filters.Add(new RequireHttpsAttribute());

Second approach using Attribute: If you do not want to use the 1st approach, you can decorate the controller class or the action method with RequireHttpsAttribute.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.