ASP.NET MVC: OAuth 2.0 REST Web API Authorization using Database First Approach
REST Web API is light weighted essential component of web development in order to share data across multiple client machines or devices e.g.
mobile devices, desktop applications or any website. Authorization of REST Web API is 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 specific username/password with the combination of a secret key, but, wait for this type to 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 the fact that who is utilizing our REST Web API whether it's the clients that we have allowed access to or 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 this means if any malicious user traces my browser activity and get the hold 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 authorize my REST Web API, it is still opened 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 REST Web API perspective. So, this new scheme of authorization is OAuth 2.0 which is a token base authorization scheme.
Let's compare OAuth 2.0 authorization scheme to the traditional username/password authorization scheme from REST Web API perspective i.e.
Today, I shall demonstrate OAuth 2.0 mechanism to authorize a REST Web API which will also give us benefit of [Authorize] attribute via OWIN security layer.
Following are few prerequisites before you proceed any further:
1) Create a new Web API project and name it "WebApiOauth2".
2) Install the following Nuget packages into your project i.e.
4) Rename "Controllers/ValueController.cs" file to "Controllers/WebApiController.cs".
5) Open, "Controllers/WebApiController.cs" file replace following code:
In above code, I have created very simple and basic REST Web API(s). Notice [Authorize] attribute is already placed at the top of the controller to make the REST Web API(s) access secure.
6) 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.
7) 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.
OAuthAuthorizationOptions are explained as follow i.e.
TokenEndpointPath -> This is the path which will be called in order to authorize the user credentials and in return it will return the generated access token.
Provider -> You need to implement this class (which I have in this tutorial) where you will verify the user credential and create identity claims in order to return the generated access token.
AuthorizeEndpointPath -> In this tutorial I am not using this property as I am not taking consent of external logins. So, if you are using external logins then you can update this path to get user consent then require access token will be generated.
AccessTokenExpireTimeSpan -> This is the time period you want your access token to be accessible. Shorter time span is recommended for sensitive api(s).
AllowInsecureHttp -> Use this property for developer environment.
More properties can be studied here.
8) 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.
9) Now, execute the project and use following link in the browser to see your newly created REST Web API method in action as follow:
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.
10) Lets, test out REST Web API in REST Web API client. I am using fire fox 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.
11) Now, I will provide the system user authorization to get access token and then use that access token as header in the REST Web API and try to his the REST Web API which will return following response i.e.
Notice in 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 token is being generated i.e. "{your_site_url}/Token".
Authorization of REST Web API can be done via specific username/password with the combination of a secret key, but, wait for this type to 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 the fact that who is utilizing our REST Web API whether it's the clients that we have allowed access to or 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 this means if any malicious user traces my browser activity and get the hold 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 authorize my REST Web API, it is still opened 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 REST Web API perspective. So, this new scheme of authorization is OAuth 2.0 which is a token base authorization scheme.
Let's compare OAuth 2.0 authorization scheme to the traditional username/password authorization scheme from REST Web API perspective i.e.
Username/Password REST Web API Authorization
|
VS
|
OAuth 2.0 REST Web API Authorization
|
||
1.
|
Access
Authorization to same or different REST Web API(s) on same server is
authenticated on each call with provided username/password.
|
Access
Authorization is authenticated only once base on the system’s existing user
credential, then on successful authorization an access token is provided for
specific period of time. REST Web API(s) call can utilize the access token
which server will not authenticate again and again.
|
||
2.
|
REST Web API(s)
call cannot track the user who is consuming the REST Web API(s). Its utilization
is based on mutual trust between Producer and consumer.
|
Only local system
users can consume the REST Web API(s), so, REST Web API call can track the
user who is consuming the REST Web API.
|
||
3.
|
Username/Password
is encrypted in base64 format. So, hackers can easily decrypt the request
headers.
|
Access
Token is encrypted in a special format. So, hackers cannot easily decrypt it
even with access to request header.
|
||
4.
|
All client
machines or devices code needs to be updated in case of change in
username/password for malicious activities.
|
Access token is
activated for specific time period. Change in system user’s credential will
not require change of code in target consumer client machines and devices.
Update credential generated new access token.
|
||
5.
|
Username/Password
is fixed.
|
Access
token is generated automatically based on system user’s credential.
|
Today, I shall demonstrate OAuth 2.0 mechanism to authorize a REST Web API which will also give us benefit of [Authorize] attribute via OWIN security layer.
- Knowledge of OAuth 2.0.
- Knowledge of ASP.NET MVC5.
- Knowledge of C# programming.
- Knowledge of REST Web API.
Download Now!
Let's begin now:1) Create a new Web API project and name it "WebApiOauth2".
2) Install the following Nuget packages into your project i.e.
- Microsoft.Owin.Security.OAuth
- Microsoft.Owin.Cors
- Microsoft.AspNet.WebApi.Core
- Microsoft.AspNet.WebApi.Owin
4) Rename "Controllers/ValueController.cs" file to "Controllers/WebApiController.cs".
5) Open, "Controllers/WebApiController.cs" file replace following code:
In above code, I have created very simple and basic REST Web API(s). Notice [Authorize] attribute is already placed at the top of the controller to make the REST Web API(s) access secure.
6) 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));
7) 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);
OAuthAuthorizationOptions are explained as follow i.e.
TokenEndpointPath -> This is the path which will be called in order to authorize the user credentials and in return it will return the generated access token.
Provider -> You need to implement this class (which I have in this tutorial) where you will verify the user credential and create identity claims in order to return the generated access token.
AuthorizeEndpointPath -> In this tutorial I am not using this property as I am not taking consent of external logins. So, if you are using external logins then you can update this path to get user consent then require access token will be generated.
AccessTokenExpireTimeSpan -> This is the time period you want your access token to be accessible. Shorter time span is recommended for sensitive api(s).
AllowInsecureHttp -> Use this property for developer environment.
More properties can be studied here.
8) 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
9) Now, execute the project and use following link in the browser to see your newly created REST Web API method in action as follow:
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.
10) Lets, test out REST Web API in REST Web API client. I am using fire fox 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.
11) Now, I will provide the system user authorization to get access token and then use that access token as header in the REST Web API and try to his the REST Web API which will return following response i.e.
Conclusion
In this article, you will learn about OAuth 2.0 authorization scheme integration with ASP.NET MVC REST Web API. You will also learn about short comparison between user/password base authorization and OAuth 2.0 token base authorization. You will also learn about OAuth 2.0 scheme authentication mechanism for system local users with entity framework database first approach.
I want to use Roles for Authorization the how can i achive with above explaination?
ReplyDeleteLook into this https://bit.ly/2FcCddb
DeleteThank you very much.
ReplyDeleteHow to enable CORS in web api2 and i am using OAuth 2 web api authorization and tried bellow code in web.config file after this only it is working for login and for accessing other page i am getting error "It has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource"
ReplyDeleteand also i tried EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
//config.EnableCors(cors);
in WebApi.config then getting same error please can you help. Thank you .
Have you use authorize attribute on other pages?
DeleteLook into this https://bit.ly/2kCGTgT try test your api on rest client as well as I don't face any errors
DeleteNo i don't use Authorize. And thank you.
ReplyDeletehow can i make it in vs2013
ReplyDeleteI can set up my new idea from this post. It gives in depth information. Thanks for this valuable information for all,.. Webdesign
ReplyDeleteHow can i use this with swagger?
ReplyDeleteThis implies you can concentrate on the more pragmatic perspectives. Nonetheless, on the off chance that you will probably be an expert website specialist, at that point you may need to take up increasingly nitty gritty courses that have a reasonable method for movement to larger amounts of capability.
ReplyDeleteWeb Design Curriculum
How can we implement the oauth in wcf service?
ReplyDeleteI really like your writing style, great information, thankyou for posting. freelance web designer peter
ReplyDeleteYou know your projects stand out of the herd. There is something special about them. It seems to me all of them are really brilliant! ui/ux design
ReplyDeleteThank you for your support
DeleteGreat post I would like to thank you for the efforts you have made in writing this interesting and knowledgeable article. buy instagram likes cheap paypal
ReplyDeleteIntriguing post. Positive that I’ll come back here. Good function. ui design agency san francisco
ReplyDeleteAs a result you’ll require ultra powerful online enterprise ideas to keep operating in getting into matters right your incredible web-based work. MLM device mockups
ReplyDeleteThanks for sharing this amazing content with us.
ReplyDeleteIf you want to learn check websites
dockerlearning
bestlinuxblog
Thanks for sharing this amazing content with us...
ReplyDeletethis is really useful and informative blog .
ReplyDeleteClick here to check all Pakistan boards exam results
Wow, Excellent post. This article is really very interesting and effective. I think its must be helpful for us. Thanks for sharing your informative. please visit
ReplyDeleteFather George Rutler
Good post. Thank you so much for sharing this post. Filmyhit, Vegamovies, Mp4moviez, A2movies, SDmovie point, Filmygod.
ReplyDeleteI enjoy each one of the posts afilmywap, hdmovie2
ReplyDeleteThis is an informative article, thank you for this. Prishta Abhyanga Therapy or Best Lower Back Pain Therapies In Singapore
ReplyDeleteThis is an informative article, thank you for this. Best Ayurvedic Treatment
ReplyDelete