OAuth Authentication For Web API

Authentication means verifying the user who is accessing the system. We have available different types of authentication in .NET programming like Windows Authentication, Forms Authentication, Claim Based Authentication, Token-Based Authentication, etc.
 

Token-based Authentication

 
In token-based authentication, you pass your credentials [user name and password], to the server, which verifies your credentials and if it is a valid user, then it will return a signed token to the client system, which has an expiration time. The client can store this token locally using any mechanism like local storage, session storage, etc. and if the client makes any other call to the server for data, then it does not need to pass its credentials every time. The client can directly pass the token to the server, which will be validated by the server and if the token is valid, then you will able to access your data.
 
OAuth
 
(Open Authorization) is an open standard for token-based authentication and authorization on the Internet.
 
OAuth versions
 
There are two versions of OAuth authorization OAuth 1 (using HMAC-SHA signature strings) and OAuth 2 (using tokens over HTTPS).
 

OAuth Tokens

 
There are two types of tokens involved in OAuth 2,
 
Access Token
 
The access token is used to for authentication and authorization to get access to the resources from the resource server.
 
Refresh Token
 
The refresh token normally is sent together with the access token.
 
The refresh token is used to get a new access token when the old one expires. Instead of the normal grant type, the client provides the refresh token and receives a new access token.
 
Token Types
 
Access tokens have a type, which defines how they are constructed.
  • Bearer Tokens
    The bearer tokens use HTTPS security, and the request is not signed or encrypted. Possession of the bearer token is considered authentication.

  • MAC Tokens
    More secure than bearer tokens, MAC tokens are similar to signatures, in that they provide a way to have (partial) cryptographic verification of the request.

How To Implement OAuth in WebAPI

 
Step 1 - Create a WebAPI Project
 
Step 2 - Add the below packages from Nuget Packages
 
Packages Required
  1. Microsoft.Owin – Implementation of OAuth Services.
  2. Microsoft.Owin.Host.SystemWeb- OWIN server that enables OWIN-based applications to run on IIS using the ASP.NET request pipeline.
  3. Microsoft.Owin.Security.OAuth- Middleware that enables an application to support any standard OAuth 2.0 authentication workflow.
  4. Microsoft.Owin.Security- Common types which are shared by the various authentication middleware components.
  5. Microsoft.AspNet.Identity.Owin-Owin implementation for ASP.NET Identity.
  6. Microsoft.Owin.Cors - components to enable Cross-Origin Resource Sharing (CORS) in OWIN middleware.
Step 3 - Owin Startup Configuration
 
Remove the Global.asax.cs file and add a startup file in place of that. Add the below line for creating owin start-up.
 
[assembly: OwinStartup(typeof(EmployeeService.Startup))]
 
If Application-specific functions like Application_Init, Application_Start, etc are needed we can make Global.asax itself as owin startup.
 
In a startup, the file adds the below configurations of Token. This will act as Web API Configuration and when every time web API is refreshed this configuration will also be refreshed.
  1. IAppBuilder AppBuilder;  
  2. public void ConfigureAuth(IAppBuilder app) {  
  3.     AppBuilder = app;  
  4.     var OAuthOptions = new OAuthAuthorizationServerOptions {  
  5.         AllowInsecureHttp = true,  
  6.             TokenEndpointPath = new PathString("/token"),  
  7.             AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),  
  8.             Provider = new SimpleAuthorizationServerProvider(),  
  9.             RefreshTokenProvider = new SimpleRefreshTokenProvider()  
  10.     };  
  11.     app.UseOAuthBearerTokens(OAuthOptions);  
  12.     app.UseOAuthAuthorizationServer(OAuthOptions);  
  13.     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());  
  14.     HttpConfiguration config = new HttpConfiguration();  
  15.     WebApiConfig.Register(config);  
  16. }  
  17. public void Configuration(IAppBuilder app) {  
  18.     ConfigureAuth(app);  
  19.     GlobalConfiguration.Configure(WebApiConfig.Register);  
  20. }  
  • TokenEndpointPath - It’s the request to be sent from the client end to generate the token.
  • AccessTokenExpireTimeSpan - This is the access token expiry time.
  • Provider/ RefreshTokenProvider - It’s a class where the token generation functionalities are included.
Step 4 - Adding Token & Refresh Token Providers
 
Token Provider
 
"SimpleAuthorizationServerProvider" class which inherits from OAuthAuthorizationServerProvider. It contains two override methods.
  • ValidateClientAuthentication – This method is to validate each service request.
  • c– This method will grant to access the application based on your credentials.
  • GrantRefreshToken – This method is used to generate the refresh token.
  1. [EnableCors(origins: "*", headers: "*", methods: "*")]  
  2. public class SimpleAuthorizationServerProvider: OAuthAuthorizationServerProvider {  
  3.         public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) {  
  4.             context.Validated();  
  5.         }  
  6.         public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) {  
  7.             var identity = new ClaimsIdentity(context.Options.AuthenticationType);  
  8.             context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin"new [] {  
  9.                 "*"  
  10.             });  
  11.             //db Logic to validate user  
  12.             If(user validated) {  
  13.                 identity.AddClaim(new Claim("Age""16"));  
  14.                 var props = new AuthenticationProperties(new Dictionary < stringstring > {  
  15.                     {  
  16.                         "userdisplayname",  
  17.                         context.UserName  
  18.                     },  
  19.                     {  
  20.                         "role",  
  21.                         "admin"  
  22.                     }  
  23.                 });  
  24.                 var ticket = new AuthenticationTicket(identity, props);  
  25.                 context.Validated(ticket);  
  26.             }  
  27.             Else {  
  28.                 context.SetError("invalid_grant""Provide username and password is incorrect");  
  29.                 context.Rejected();  
  30.             }  
  31.         }  
  32.         public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context) {  
  33.             var newIdentity = new ClaimsIdentity(context.Ticket.Identity);  
  34.             newIdentity.AddClaim(new Claim("newClaim""newValue"));  
  35.             var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);  
  36.             context.Validated(newTicket);  
  37.             return Task.FromResult < object > (null);  
  38.         }  
Refresh Token Providers
 
Refresh Token Provider is used to produce refresh tokens. It inherits ‘AuthenticationTokenProvider’. It contains two methods,
  1. public class SimpleRefreshTokenProvider: IAuthenticationTokenProvider {  
  2.     private static ConcurrentDictionary < string, AuthenticationTicket > _refreshTokens = new ConcurrentDictionary < string, AuthenticationTicket > ();  
  3.     public async Task CreateAsync(AuthenticationTokenCreateContext context) {  
  4.         var guid = Guid.NewGuid().ToString();  
  5.         _refreshTokens.TryAdd(guid, context.Ticket);  
  6.         context.SetToken(guid);  
  7.     }  
  8.     public async Task ReceiveAsync(AuthenticationTokenReceiveContext context) {  
  9.         AuthenticationTicket ticket;  
  10.         if (_refreshTokens.TryRemove(context.Token, out ticket)) {  
  11.             context.SetTicket(ticket);  
  12.         }  
  13.     }  
  14. }  
Step 5 - Create a Controller
 
Add a new controller and add a method to it which is having [Authorize] attribute.
  1. public class EmployeeController: ApiController {  
  2.     [HttpGet]  
  3.     [Authorize]  
  4.     public List < Employee > GetEmployees() {  
  5.         using(var db = new TESTEntities()) {  
  6.             var employees = db.Employees.ToList();  
  7.             return employees;  
  8.         }  
  9.     }  
  10. }  
GetEmployees method will only return 200 OK Success message if bearer token is passed in headers. Otherwise the request will return 401 Unauthorized code.
 
We can customize the authentication attribute according to our logic if needed.
 
Step 6 - Enable CORS in WebAPIconfig
 
CORS is a mechanism that allows restricted resources on a web page to be requested from another domain, outside the domain from which the resource originated. Enable CORS by adding following lines in WEBAPIconfig,
  1. EnableCorsAttribute cors = new EnableCorsAttribute("*""*""*");  
  2. config.EnableCors(cors);  

How To Run OAuth Web API

 
By following the above 6 Steps OAuth WebAPI is created. Now, let us see how to frame service requests for token generation, Refresh Token, etc.
 
Host the Web API in IIS in Integrated Pipeline Mode.
 
Call the ~/token method below format.
  • Headers – Set Application Type as application/x-www-form-urlencoded
  • Body – Pass user credentials (Username & Password), and grant_type as ‘password’
In Response, if data passed are correct and validated successfully, Token, Token type along with its expiry time and refresh token will be returned. The access token is valid for 59s according to the above response, It can be regenerated by passing the refresh token request.
 
To Refresh the token call the ~/token method in the below format,
  • Headers – Set Application Type as application/x-www-form-urlencoded
  • Body – Pass refresh_token as <refresh_token_value>, and grant_type as ‘refresh_token’
For Accessing a service request with Authorize attribute frame the request in the below format.
  • Headers – Set Application Type as application/x-www-form-urlencoded, Set Authorization as ‘bearer <access_token_value>’

Similar Articles