ASP.NET MVC - OAuth 2.0 REST Web API Authorization Using Database First Approach

REST Web API is a light-weight essential component of web development in order to share the data across multiple client machines or devices e.g. mobile devices, desktop applications or any website. Authorization of REST Web API is an equally important part for sharing data across multiple client machines and devices in order to protect data sensitivity from any outside breaches and to authenticate the utilization of the target REST Web API.

Authorization of REST Web API can be done via a specific username/password with the combination of a secret key, but, for this type of authorization scheme, REST Web API access needs to be authenticated per call to the hosting server. Also, we as the owner of the server have no way to verify who is utilizing our REST Web API, whether it's the clients that we have allowed access to or if some malicious user is also using our API(s) without our knowledge. Finally, since the username/password is packed to a base64 format automatically by the browser, if any malicious user traces my browser activity and gets ahold of my REST Web API calls they can easily decrypt base64 format and could use my REST Web API for malicious activities.

Hmmmmm.....scary stuff! Not to mention that despite the fact that I have authorized my REST Web API, it is still open for malicious users to utilize without even my knowledge. So, what to do? To answer that a new authorization scheme is introduced which can also be utilized in Login flow of any web application as well, but, I will be focusing on it from a REST Web API perspective. So, this new scheme of authorization is OAuth 2.0 which is a token based authorization scheme.
 

In this tutorial, I shall demonstrate OAuth 2.0 mechanism to authorize a REST Web API which will also give us the benefit of [Authorize] attribute via OWIN security layer.

Following are a few prerequisites before you proceed any further,

  1. Knowledge of OAuth 2.0.
  2. Knowledge of ASP.NET MVC5.
  3. Knowledge of C# programming.
  4. Knowledge of REST Web API.

The running working solution source code is being developed in Microsoft Visual Studio 2015 Enterprise and SQL Server 2014 is being used for Database Development. You can reach out the author for source code.

Let's begin now:

Step 1

Create a new Web API project and name it "WebApiOauth2".

Step 2

Install the following NuGet packages into your project, i.e.,

  1. Microsoft.Owin.Security.OAuth
  2. Microsoft.Owin.Cors
  3. Microsoft.AspNet.WebApi.Core
  4. Microsoft.AspNet.WebApi.Owin

Step 3

Now open "App_Start/WebApiConfig.cs" file and add following two line of code which will add authentication filter for Oauth 2.0 authorization scheme and surpass any existing authorization scheme i.e.

...
            // Web API configuration and services  
            // Configure Web API to use only bearer token authentication.  
            config.SuppressDefaultHostAuthentication();  
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 
...

Step 4

Now, open "App_Start/Startup.Auth.cs" file and add following lines of code in which "PublicClientId" is used when "AuthorizeEndpointPath" is utilize for unique instantiate from client side. Following lines of code will enable the OAuth 2.0 authorization scheme i.e
...
            // Configure the application for OAuth based flow  
            PublicClientId = "self";  
            OAuthOptions = new OAuthAuthorizationServerOptions  
            {  
                TokenEndpointPath = new PathString("/Token"),  
                Provider = new AppOAuthProvider(PublicClientId),  
                AuthorizeEndpointPath = new PathString("/Account/ExternalLogin"),  
                AccessTokenExpireTimeSpan = TimeSpan.FromHours(4),  
                AllowInsecureHttp = true //Don't do this in production ONLY FOR DEVELOPING: ALLOW INSECURE HTTP!  
            };  
  
            // Enable the application to use bearer tokens to authenticate users  
            app.UseOAuthBearerTokens(OAuthOptions); 
...
Step 5

Now, create "Helper_Code/OAuth2/AppOAuthProvider.cs" file which is provider class in which you will configure authorization logic. "GrantResourceOwnerCredentials(...)" method is the key method which is called when TokenEndpointPath is called. Notice that "GrantResourceOwnerCredentials(...)" method is used by "grant_type=password" scheme. If you are using "grant_type=client_credentials" scheme than you need to override "GrantClientCredentials(...)" method. Other inherited methods are part of "OAuthAuthorizationServerProvider" class, use them as it is. In "GrantResourceOwnerCredentials(...)" method we are verifying the system login user and then create the require identities claims and then generate the returning access token ticket i.e.

#region Grant resource owner credentials override method.  
  
/// <summary>  
/// Grant resource owner credentials overload method.  
/// </summary>  
/// <param name="context">Context parameter</param>  
/// <returns>Returns when task is completed</returns>  
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)  
{  
    // Initialization.  
    string usernameVal = context.UserName;  
    string passwordVal = context.Password;  
    var user = this.databaseManager.LoginByUsernamePassword(usernameVal, passwordVal).ToList();  
  
    // Verification.  
    if (user == null || user.Count() <= 0)  
    {  
        // Settings.  
        context.SetError("invalid_grant", "The user name or password is incorrect.");  
  
        // Retuen info.  
        return;  
    }  
  
    // Initialization.  
    var claims = new List<Claim>();  
    var userInfo = user.FirstOrDefault();  
  
    // Setting  
    claims.Add(new Claim(ClaimTypes.Name, userInfo.username));  
  
    // Setting Claim Identities for OAUTH 2 protocol.  
    ClaimsIdentity oAuthClaimIdentity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);  
    ClaimsIdentity cookiesClaimIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType);  
  
    // Setting user authentication.  
    AuthenticationProperties properties = CreateProperties(userInfo.username);  
    AuthenticationTicket ticket = new AuthenticationTicket(oAuthClaimIdentity, properties);  
  
    // Grant access to authorize user.  
    context.Validated(ticket);  
    context.Request.Context.Authentication.SignIn(cookiesClaimIdentity);  
}  

#endregion 

Step 6

Now, execute the project and use the following link in the browser to see your newly created REST Web API method in action as follows,

yourlink:port/api/WebApi   

In the above snippet, you will notice that since now our REST Web API has been authorized, therefore, we cannot directly execute the REST Web API URL in the browser. 

Step 7

Let's test out REST Web API in REST Web API client. I am using Firefox plugin i.e. "RESTED". At, first, I simply try to hit the REST Web API without any authorization details and I will get following response i.e.

Step 8

Now, I will provide the system user authorization to get access token and then use that access token as a header in the REST Web API and try to his the REST Web API which will return the following response, i.e.

 

 
Notice in the above snippets that access token is provided as "Authorization" header with "Bearer access_token" scheme in order to call the REST Web API. Also, notice the path when the token is being generated i.e. "{your_site_url}/Token".

Conclusion

In this article, you learned about OAuth 2.0 authorization scheme integration with ASP.NET MVC REST Web API. You also learned about the short comparison between user/password based authorization and OAuth 2.0 token based authorization. You also learned about OAuth 2.0 scheme authentication mechanism for local system users with the Entity Framework database first approach.