Learn how to enforce HTTPS across your entire API with a few lines of code. Nate demonstrates how to configure MVC to require HTTPS for all routes, and discuss how to handle HTTPS in both development and production.
- [Instructor] The biggest component of transport security is enabling HTTPS, also called SSL or TLS. Since kestrel will be behind a reverse proxy that can handle the low-level details of HTTPS, we need to turn HTTPS on at the proxy layer. We're using iis express for development, and iis express does not have SSL turned on by default. To enable it, we can right-click on the project and choose properties. On the debug tab, I can check enable SSL to turn on SSL support.
Now the application will respond to plain HTTP requests on 53136 but encrypted SSL requests on 44323. I can save this with Ctrl + S and then close the properties window. These settings are stored in launchsettings.json under the properties element in the solutions explorer. HTTPS is now enabled, but it's optional. We want it to be enforced, so that if a client accesses our API over regular HTTP, they're redirected automatically to HTTPS.
On controllers, you can use the require HTTPS attribute. For example, I can open the root controller and add require HTTPS. However, this only enforces HTTPs for this one controller. We can apply the attribute to the entire application at once by adding it as a filter in the startup class. I'm going to remove this. In the startup class, in the configure services method and the AddMvc section, I can say require HTTPS for all controllers and add this to the filters collection.
We need to add typeof(RequireHTTPSAttribute), which is the same exact class that you can add as an attribute on the controllers. This'll take care of automatically redirecting clients over to an encrypted HTTPS connection. There's one more step we need to do. By default, the require HTTPS filter will redirect plain HTTP requests over to HTTPS on the default port 443. In production, that's fine, because your site will be running on port 443. However, during development, as we saw before, the HTTPS port is different, it's a randomly generated port.
The require HTTPS attribute doesn't know about this port by default, so in development, it'll break. To fix this, we can manually read the value from launchsettings.Json and let the filter know which port to redirect to. At the top of my startup class, I can add a private, read-only, knowable integer called HTTPS port. And then in the constructor of the startup class I can add a little bit of code below the existing code. I'll say get the HTTPs port only in development.
I'll check the i-hosting environment object to see are we currently in development, and if so, I need to read the values from launchsettings.Json. So I can use the same type of code as above, using a new configuration builder. Set the base path as the content root of my project, and then add the Json file properties\\launchsettings.json And then call .Build.
That's referring to this properties folder and this launchsettings.json file, which has this value that we want to pull out. Now we can say we want to set that integer variable to the config. We'll get a value of type integer from the path iis settings iis express ssl port. And this path syntax, there's a typo, this path syntax matches up the object graph iis settings iis express ssl port.
Now, above the filter call, we can say options dot ssl port and set it to the port we grabbed out of the configuration. And again, in production, this will just completely be ignored, and the clients will be redirected to the default port of 443 automatically. Now that HTTPS is enforced across the entire API and we have the correct port, let's go ahead and test the connection.
- REST vs. RPC
- Using HTTP methods (aka verbs)
- Returning JSON
- Creating a new API project
- Building a root controller
- Routing to controllers with templates
- Requiring HTTPS for security
- Creating resources and data models
- Returning data and resources from a controller
- Representing links (HREFs)
- Representing collections
- Sorting and searching collections
- Creating forms
- Caching and compression
- Authentication and authorization for RESTful APIs