- Make a true RESTful Web API (enable CRUD functions by HTTP POST, GET, PUT, and DELETE).
- Enable Secure Authorization for API calls (use the OAuth 2.0 authorization framework).
- Enable Transport Layer Security, i.e., SSL (reject every non-HTTPS request).
- A Windows Computer.
- Microsoft Visual Studio Express 2013 for Web (free download).
- Securing (ASP.NET) Web API based architectures (video).
- ASP.NET Web API 2 (tutorials).
- OAuth 2.0 Authorization Framework (specification).
- Open Web Interface for .NET (OWIN).
- Writing an OWIN Middleware in the IIS integrated pipeline (tutorial).
- Enabling Cross-Origin Requests in ASP.NET Web API (tutorial).
An Skeleton Project by ASP.NET Web API 2 (oAuth 2.0 and CORS support)
1. Creating the Project
Create an ASP.NET Web Application (Visual C#) in Microsoft Visual Studio Express 2013 for Web. Let’s name it Skeleton.WebAPI. Select the Web API template and Change Authentication from ‘No Authentication’ to ‘Individual User Accounts’, [screenshot].
The ‘Controllers/ValuesController.cs’ holds our sample API endpoints. Run the project and in the browser go to ‘http://localhost:port/api/values‘ and you should get a 401 Unauthorized.
2. Writing the Sample API Endpoints
In ‘Controllers/ValuesController.cs’, comment out [Authorize] to disable authorization. Run the project and in the browser go to ‘http://localhost:port/api/values‘ and now you should get 2 values.
Change ‘Controllers/ValuesController.cs’ with the following code to enable CRUD operations, [Link]. This controller now accepts HTTP GET, POST, PUT, and DELETE to receive a list of values, add a value, update a value, and delete a value. Currently, these values are stored in the Web Server memory, but ideally they will be saved in the database. I recommend using Repository Pattern for it, [More info].
Let’s write a simple html page to call these api endpoints. For example, the following code can be used for receiving the list of current values:
3. Enabling Cross-Origin Resource Sharing (CORS) support
To Enable CORS support, first install Microsoft.AspNet.WebApi.Cors by NuGet. Open up ‘App_Start/WebApiConfig.cs’ and add the following line in the Register method:
Then open your API Controller, ‘Controllers/ValuesController.cs’ and add the following line before the class definition:
It tells the server the accept all types requests. You can obviously filter out the requests. For more customization, read this.
4. Cleaning up the Views from the project
You should notice that the VS template created some views in the project. As we are building a pure Web API, there will be no views. So, delete App_Start/[BundleConfig,RouteConfig].cs, Areas/*, Content/*, Controllers/HomeController.cs, fonts/*, Scripts/*, Views/*, Project_Readme.html, and favicon.ico. Finally, remove the following lines from Global.asax.cs:
At this point, we have completed Objectives 1 and 2. The code up to this point can be downloaded from https://github.com/rfaisal/ASPWebAPI_Example_OAuth_CORs/tree/crud_cors_only_v1.
5. Adding oAuth 2.0 support
In the simplest terms, here is how oAuth (or most token based authorization) works. The client request an Access Token from the Authorization Server. The Authorization Server verifies the identity of the client somehow and returns an Access Token, which is valid for a limited time. The client can use the Access Token to request resources from the Resource Server as long as the Access Token is valid. In our case, both Authorization Server and the Resource Server are the same server, but they can be separated easily.
Ideally, you need to write an OWIN Middleware in the IIS integrated pipeline for oAuth. But, the VS template generates the necessary codes for the OWIN Middleware. Watch this video to learn more about these implementations.
Now, we will add 2 more functionality, namely registering a new user and requesting a Access Token based on the username and password.
The user registration controller (Controllers/AccountController.cs) is already generated by the Template. First add the following line in the AccountController to allow CORS:
Then you can call the end point http://localhost:port/api/Account/Register/ and HTTP POST an object consisting of UserName, Password, and ConfirmPassword to register an account.
Now, the endpoint for requesting an Access Token is also generated by the template. The code is in App_Start/Startup.Auth.cs :
It says that the client can request an Access Token by calling http://localhost:port/Token endpoint and HTTP POSTing grant_type, username, and password as Url Encoded String. This endpoint, however, is not an API endpoint. To enable CORS to this endpoint we need to add the following code segment to the ConfigureAuth function of App_Start/Startup.Auth.cs file.
We are almost done. We have to modify all the API calls to pass this Access Token. First of all, un-comment [Authorize] attribute on the ValuesController and run to make sure that all of the API calls are returning 401 Unauthorized. Add the following property with each ajax call to pass the Access Token as the Bearer Token:
At this point, we have completed Objectives 1, 2, and 3. The code up to this point can be downloaded from https://github.com/rfaisal/ASPWebAPI_Example_OAuth_CORs/tree/crud_cors_oauth.
6. Enforce SSL for all API calls
Any information that is not transferred over SSL is not secure. So, we are going to reject any request that doesn’t come over HTTPS. First we will write a filter that can be used to filter out non-https requests. Here is the code:
When we add this class to our project, we have [RequireHttps] available. Add this attribute to all the Controller class. For example,
Finally, we also want the Token request to be enforced over HTTPS. To do so, remove ‘AllowInsecureHttp = true’ from Startup.Auth.cs.
To test the SSL enforcement, change the SSL Enabled property to true for the Development Server in Visual Studio and use the SSL Url, [screenshot].
The final code can be downloaded from https://github.com/rfaisal/ASPWebAPI_Example_OAuth_CORs/tree/crud_cors_oauth_ssl.
A screenshot of the client, [screenshot].
Tagged: api, asp-net, authentication, authorization, C-Sharp, code, cors, design patterns, git, github, https, oauth, quality code, restfull, security, source control, ssl, visual-studio, web-api, windows