Introduction
REST Web API is a lightweight 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 an equally important part of 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 the 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 the OAuth 2.0 mechanism to authorize a REST Web API, which will also give us the benefit of the [Authorize] attribute via the OWIN security layer.

Following are a few prerequisites before you proceed any further.
- Knowledge of OAuth 2.0.
- Knowledge of ASP.NET MVC5.
- Knowledge of C# programming.
- 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 to 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.
- Microsoft.Owin.Security.OAuth
- Microsoft.Owin.Cors
- Microsoft.AspNet.WebApi.Core
- Microsoft.AspNet.WebApi.Owin
Step 3. Now open the "App_Start/WebApiConfig.cs" file and add the following two lines of code, which will add an authentication filter for the 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 the "App_Start/Startup.Auth.cs" file and add the following lines of code in which "PublicClientId" is used when "AuthorizeEndpointPath" is utilized for unique instantiate from the client side. The 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 the "Helper_Code/OAuth2/AppOAuthProvider.cs" file, which is the provider class in which you will configure authorization logic. The "GrantResourceOwnerCredentials(...)" method is the key method that is called when TokenEndpointPath is called. Notice that the "GrantResourceOwnerCredentials(...)" method is used by the "grant_type=password" scheme. Suppose you are using the "grant_type=client_credentials" scheme, then you need to override the "GrantClientCredentials(...)" method. Other inherited methods are part of the "OAuthAuthorizationServerProvider" class. Use them as it is. In the "GrantResourceOwnerCredentials(...)" method, we verify the system login user and then create the required identity 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 then, 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 the REST Web API client. I am using the Firefox plugin, i.e., "RESTED". At first, I simply tried to hit the REST Web API without any authorization details, and I got the following response i.e.

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

Note. In the above snippets, that access token is provided as an "Authorization" header with a "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 the OAuth 2.0 scheme authentication mechanism for local system users with the Entity Framework database first approach.

Lijish BhavanPosted Apr 25, 2024, 5:46 PM
Can i have the source code for this demo.
sgcino ngemaPosted May 9, 2023, 5:49 PM
Hi Asma , can you please share your source code.
Babar MoinPosted Nov 30, 2022, 6:04 PM
Hi I have an issue with using this approach , e.g. my user already has auth token, and authorize to access information, meanwhile system administrator change the users password or disable user but still the user can access the information with previous token until the token expire. how can we handle the issue???
Krishna ChandakPosted Mar 29, 2022, 1:00 PM
Hi Asma, thanks for sharing your experience in WebApi using OAuth 2.0 approach in this. I need to know what are the namespace we are using in AppOAuthProvider.cs" file. Thanks in advance and your effort is highly appreciated :)
Matt SwainstonPosted Jan 11, 2022, 2:58 PM
Hi Asma, Loving your work, can I get the source to this? I am trying to use oAuth to secure my webapi and the first piece of code - config. is not defined - not sure what I am missing? The source would help.....
Graham MannPosted Nov 26, 2021, 3:26 AM
Hi there, this is a great article and I've learnt alot form it and from your blog. I have a problem now as I have multiple servers behind a load balancer, so I need to use distributed session state. What would be the best way to do this?
Scott LyonPosted Oct 27, 2021, 4:22 PM
Hi. Is there any chance you could post the completed source code? I'm trying to work through the example (but admittedly using VS 2019, not 2015) and I'm not sure what I'm missing (or what may have changed between versions). Thanks!
Hassan ShabbirPosted Apr 26, 2021, 8:22 AM
Great Articel how i wanted . I am getting this error and i cant get this why this error come in backend. "error": "unsupported_grant_type" where i am doing mistake ?
Tauqir RaoPosted Apr 17, 2021, 6:04 PM
Unsatisfactory,
BadruzzamanPosted Apr 17, 2021, 8:39 AM
Thank you so much for the article it's really helpful
Cemal SenerPosted Mar 30, 2021, 5:38 AM
Great articel, thanks, for newbies a life rescue...
Mauricio GarudaPosted Mar 25, 2021, 5:22 PM
Hello, how to configure grant_type=client credentials
Tasneem NomaniPosted Mar 17, 2021, 4:15 PM
Hello, DO you have an example where you consume the api not using postman, but using mvc web app
Tasneem NomaniPosted Mar 12, 2021, 4:51 PM
Hello,I am trying to create a web mvc client that will call api using oauth2 cwith client credentials. CAn you please share some example how to consume the api
vijay krishnaPosted Mar 3, 2021, 4:41 PM
This approach works for me, But when i am trying to extract the token using JWT, its saying invalid token. So how i can I extract and see the information inside the token. I am trying to copy/paste the token in this website(https://jwt.io/) to see the content from the token. but is not working. any idea how can we extract information from this token?
Karthikeyan PPosted Mar 3, 2021, 10:57 AM
How can I implement this into my asp.net core 5.0 web api?
Norell MantillaPosted Feb 21, 2021, 2:51 PM
What if the user log out, does the token expires?
Shinu JohnPosted Feb 11, 2021, 12:06 PM
The article you have provided is very helpful. I was able to follow the steps and create it. I saw in many articles that the password grant type is deprecated. Is this correct. Could you please help me with an example on the grant type as Authorization code.
thatX thatXPosted Jan 13, 2021, 9:19 AM
How do you create the entity deploy(AdoEntityModel.edmx). can you briefly explain?. cause im stuck at step 8 and the project wont build.
Sun LightPosted Nov 11, 2020, 6:56 AM
Hiya this is great explanation. Got it running almost but am getting the error - No OWIN authentication manager is associated with the request, couldn't find ways to resolve this. Can you help please?
GuruPosted Oct 11, 2020, 1:38 AM
The same issue as jagadeesan vengudusamy, 404 not found. how to resolve. Thanks
standley peterPosted Oct 9, 2020, 4:15 AM
Hi Asma, thanks for this. I am very new to C# environment and still in the learning process. How may I convert his to become .net core web service?
Mark MicallefPosted Sep 17, 2020, 8:12 AM
Hi Asma, Thanks for this. When I get the token, how can I decipher it on the client side to extract claims please? I tried loading it into https://jwt.io but apparently it is encrypted but I cannot find the place in your code where you specify the key.
Sebastian ContrerasPosted Jul 26, 2020, 9:27 PM
Hi Asma, It is possible change username and password parameters to Application/json ? Thanks!
Qina JerePosted Jul 21, 2020, 8:08 AM
Hey Asma Khalid, how can i add basic authentication when requesting for a token?
Theavuth NhelPosted Jul 19, 2020, 10:03 PM
Hey Asma Khalid this is a great work! I seem have some missing. I got the error CS0246 C# The type or namespace name could not be found (are you missing a using directive or an assembly reference?). How to fix it? I'm newly of ASP.NET
Mohammed HafizPosted Jul 18, 2020, 3:11 PM
How Long this token remains valid? Every time api call is done, they need to generate token?
suman nathPosted Jul 17, 2020, 5:44 AM
Hi Asma, very helpful article, but I face one issue after deploy and open outside access, Access token not working, its still says "Authorization has been denied" can anyone had any issue ?
Shruti NayakPosted Jun 26, 2020, 1:58 AM
Hey Asma, Thank you for such a helpful article. It indeed is a great help. I have an asp.net website to which i would like to implement oAuth 2.0 authorize endpoint. Please guide.
Bhaskar JoardarPosted Jun 12, 2020, 8:21 AM
A great article Asma. This worked fine for me but I have a little different requirement. Instead of grant_type 'password', I want to use 'Client_Credentials' where the scope parameter must be used. Could you please help me in that.
jagadeesan vengudusamyPosted May 30, 2020, 7:49 AM
Hi Asma when i am using post method to generate token its shown 404 content not found. your code is everything is fine for me but i click send request showing error like this. Please help me out
Kamran RashidPosted May 29, 2020, 6:35 AM
What if i want to create an console application and try to consume any OAuth authentication based web service. What will be the code for that
C DPosted May 1, 2020, 2:54 PM
Hi, Thanks for the article. Could you please let me know how to do Logout process (and expire/invalidate token)?
Burak KösePosted Mar 9, 2020, 6:49 AM
Very good explanation and well working demo. Much appreciated.
mr khanPosted Jan 23, 2020, 3:33 PM
I don't want to use the Entity Framework?
jubula samalPosted Jan 21, 2020, 5:15 PM
You are awesome. What a post. executed everything properly in one attempt.
Bryan GomezPosted Jan 8, 2020, 8:32 PM
Hello, how did you manage to add more properties on the token result? From my result it only shows 3 properties "access_token, token_type, expires_in".
Abhijit PandyaPosted Dec 23, 2019, 8:30 AM
Hello Asama, Thank you very much. very nice article and its complete helpful me to implement oAuth 2 with my web API project. in response i m getting keys "access_token", , "token_type", "expires_in", "refresh_token",. can i add any extra key in response , i want return ID. if yes then how ?
Madhu VenugopalPosted Dec 1, 2019, 11:58 PM
ERROR:On clicking the Login link on the home page shows this: Server Error in '/' Application. The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly. Requested URL: /Account/Login There is no AccountController at all...
Sarin SomanPosted Nov 17, 2019, 6:41 AM
Hi Asma, Great article. thank you so much. Can you guide me how can i pass the following parameters through header to get the token. Grant_type : Instead of password i have to use "client credentials" Client_Id :Instead of username i have to put this. Password will be same password. i have to pass these three parameters through header to get the token. is that possible? if yes please guide me.
Deepak SharmaPosted Oct 30, 2019, 7:34 AM
When I try to run my project it gives me an error "No OWIN authentication manager is associated with the request". But it works fine if I try to run your source code. Some people pointed out that it is caused by the lines "config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));" in the webAPiConfig.cs file but work fine in your source code. Could you please point out if am doing anything wrong P.S I didn't get the startup files autogenerated and thus had to create them using OWIN startup class option manually .
Mamoon RasheedPosted Sep 17, 2019, 11:41 AM
Thank You so much for this article... it helped me alot and i was about change my domain logic to WebApi domain preferences... thank god... God Bless
nirav godhaniPosted Sep 6, 2019, 3:05 PM
I am running the application and testing using Firefox plugin It gives error as output while requesting Token in route "http://localhost:3097/Token" as : {"error":"unsupported_grant_type"}
cuong doPosted Sep 6, 2019, 1:55 AM
Hello. It's a great posts... I get stuck in Token Introspection Endpoint. How can the client know the endpoint of Token Introspection in Oauth2 Server? can you give me an example of that... thank you so much!
Bartosz KaczubaPosted Aug 29, 2019, 3:06 AM
Hi. Can You post client sample for xamarin forms (Android) ?
Moorosi MofokengPosted Aug 26, 2019, 1:32 PM
Hi Asma. I downloaded your project. I am able to get the token but i cannot use the token to call the RESR Web Api. It still says authorization has been denied for this user. Am i missing something? Please help.
MatiasPosted Aug 4, 2019, 11:18 AM
Hi Asma! What is the approach to renew token? Imagine I have an Android App and I don't want to force the user to re-login to continue using the App. Any idea?
Burak CPosted Jul 13, 2019, 2:38 PM
Hello,I have bearer token (Bearer asassasasasasas) already.I don't need to generate new token key.How can I use it windows forms in c#? Could you please help me?
Muhammad BilalPosted Jul 12, 2019, 6:46 AM
And we can implement sliding on it so that every time use access api method it reinitialize access time please guide?
Muhammad BilalPosted Jul 12, 2019, 6:45 AM
How to get refresh token
Brunno ObristoPosted Jul 4, 2019, 12:36 PM
I'm having many errors that don't have a visible solution. Like "UseExternalSignInCookie", i can't even import something to fix the error.
ernesto vazquezPosted Jun 24, 2019, 5:20 PM
DOES THIS EXAMPLE HANDLE AUTHORIZATION AND AUTHENTICATION?
Vuvuzela OléPosted May 27, 2019, 12:16 PM
Hi, how do I use Azure active directory for authentication/token generating with this code?
Nitin AshiyaniPosted May 17, 2019, 5:37 AM
Hello Asma, i downloaded your project, but i cant get step 10 in your project.
Vaughan TrebilcoPosted Mar 3, 2019, 9:08 PM
Or how would i implement token refresh
Vaughan TrebilcoPosted Mar 3, 2019, 9:05 PM
Hello Asma. Is there a way to make the token never expire?
Vaughan TrebilcoPosted Feb 24, 2019, 2:46 PM
Hello Asma. In a controller I can get the user name associated with a token like this: User.Identity.Name; How do I get the token value so I can store it in a database?
Vaughan TrebilcoPosted Feb 12, 2019, 1:03 PM
Hello Asma. I asked this question previously and passed your reply to a colleague. What do you think about this reply below? “The delete is for a user to logout of the app. I’m not sure what you read but it’s a very basic functionality of any service I know of. All you have to do on your end is either delete the token or flag it as such so that it can’t be used.”
reza shiraziPosted Feb 10, 2019, 6:57 PM
Hi, thanks for this article, can this generated token be used in asp.net mvc controller to authorize action methods? ( not from javascript). Imagine we authenicate asp.net mvc with the api and get the token and save it in a cookie. Then how can we auhtorize action methods by using that token?
Vaughan TrebilcoPosted Feb 7, 2019, 4:11 PM
Thanks again this article has been extremely helpful. I’m not sure why but I have a spec that asks to delete the registration despite the timeout feature. Response should be “Registration is removed. The token is now invalid”. Do you know how this would be done?
Marco GaertnerPosted Feb 2, 2019, 2:12 AM
Wow, this was awesome. I searched high and low for something like this: updated, simple, beautiful, full example. It was hard! Kudos to you!
Osama AhmedPosted Dec 31, 2018, 6:06 PM
How i can logout Specific user
Niklas RydenPosted Dec 13, 2018, 4:53 AM
Hi Asma nice tutorial. When i run code in VS it works but when i try to use it in IIS 7 I get folowinfg error:The controller for path "Token" was not found or does not implement IController
Vaughan TrebilcoPosted Dec 12, 2018, 2:14 PM
Yes I know but I need to call other methods that require username as a parameter. So how do I get the username that was used for the initial username and password login?
Vaughan TrebilcoPosted Dec 11, 2018, 4:12 PM
Hello Asma. Great article thank you. In the web api controller "Get" method how do I get the use's record id or user name?
lamaahmadPosted Nov 10, 2018, 12:32 PM
Very nice article but I have downloaded the source code and trying it using postman but when requesting /Token it says : "error": "unsupported_grant_type". Any clarification please
Behnam SAPosted Oct 26, 2018, 6:05 AM
Hi, I did as this article said but at the end I just get 500 internal error. I checked it twice everything is like what writer has been wrote. can any body help whats the problem?
sunil patelPosted Oct 22, 2018, 7:33 AM
Thanks for the information but updating the credential should not generated a new access token as you have mentioned in description.Please describe the point if I am missing something here.
Uttam ChaturvediPosted Sep 28, 2018, 1:30 AM
Thanks for your comment Asma. I will check and come to you as soon as possible.
Ajay GuptaPosted Sep 17, 2018, 2:04 AM
How to use with begin form ?
Uttam ChaturvediPosted Sep 14, 2018, 1:49 AM
Hello Asma, Very nice article for the beginners.
Dy Dany JustinePosted Sep 13, 2018, 9:48 AM
I would like to you that , can i use the same token to access other browser without login ?
AlessandroPosted Aug 6, 2018, 9:04 AM
Nice and clean article! Good job.
RameshPosted May 14, 2018, 6:35 AM
Nice article, thank you for writing the article in detail.