Showing posts with label Authentication. Show all posts
Showing posts with label Authentication. Show all posts

Sunday, 22 January 2023

JWT authentication in ASP.NET Core WebAPI

Using JWT (JSON Web Tokens) in a Web API is a common approach for handling authentication and authorization. Here's a concise guide on how to implement JWT in a Web API, typically using a framework like ASP.NET Core, but the principles apply to other frameworks as well.

Step 1: Install Necessary Packages

For ASP.NET Core, you'll need to install the following NuGet packages:

  1. Microsoft.AspNetCore.Authentication.JwtBearer
  2. System.IdentityModel.Tokens.Jwt

Step 2: Configure JWT in Startup

In your Startup.cs file, configure JWT authentication in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    // Other service configurations...

    var key = Encoding.ASCII.GetBytes("your_secret_key_here"); // Use a strong secret key
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false; // Set to true in production
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

    services.AddControllers();
}

Step 3: Create a JWT Token

You'll need a method to generate the JWT. This typically occurs during login:

  public string GenerateJwtToken(string username)
  {
// Define JWT claims
      var claims = new[]
      {
          new Claim(JwtRegisteredClaimNames.Sub, userid), // Registered Claims
new Claim(JwtRegisteredClaimNames.Name, username), // Registered Claims
          new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("role", "admin"), // Custom Claims
new Claim("email", "johndoe@example.com") // Custom Claims
      };
 
// Define the security key
string secretKey = "your_secret_key_here";
      var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));

// Define the signing credentials (HMACSHA256 algorithm)
      var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
 
      var token = new JwtSecurityToken(
          issuer: "your-issuer", // Can be your app name
          audience: "your-audience", // Can be a target application or service
          claims: claims,
          expires: DateTime.Now.AddMinutes(30),
          signingCredentials: creds);
 
       // Serialize the token to a string
       var tokenHandler = new JwtSecurityTokenHandler();
       string jwtToken = tokenHandler.WriteToken(token);

      return jwtToken ;
  }

Step 4: Secure Your API Endpoints

Use the [Authorize] attribute to protect your API endpoints:

  [Authorize]
  [ApiController]
  [Route("[controller]")]
  public class WeatherForecastController : ControllerBase
  {
      [HttpGet]
      public IActionResult Get()
      {
          return Ok(new { Message = "This is a protected endpoint!" });
      }
  }

Step 5: Handling User Login

Create a login endpoint to authenticate users and return a JWT:

  [HttpPost("login")]
  public IActionResult Login([FromBody] LoginModel login)
  {
      // Validate user credentials (this is just an example)
      if (login.Username == "test" && login.Password == "password") // Replace with actual validation
      {
          var token = GenerateJwtToken(login.Username);
          return Ok(new { Token = token });
      }
 
      return Unauthorized();
  }

Step 6: Testing

Use a tool like Postman to test your endpoints:

  1. Call the login endpoint with valid credentials to receive a JWT.
  2. Use the received token in the Authorization header (Bearer <token>) when accessing protected endpoints.

Where jwt tokens are stored on on server

JWT (JSON Web Tokens) are typically not stored on the server in the same way as session data. Instead, they are often used in a stateless manner, meaning the server does not maintain a session for each user. Here’s how it generally works:

  1. Client-Side Storage: After authentication, the server sends the JWT to the client, which usually stores it in local storage or cookies.

  2. Stateless Authentication: Each time the client makes a request, it sends the JWT along (typically in the Authorization header). The server validates the token without needing to store any session data.

  3. Optional Revocation: If you need to implement token revocation or blacklisting, you might maintain a list of revoked tokens on the server, but this is an additional layer of complexity that somewhat counters the stateless principle.

  4. Expiry: JWTs usually have an expiration time, after which they are considered invalid. This reduces the need for server-side storage since expired tokens can be discarded.

In summary, JWTs are mainly stored client-side, while the server verifies them as needed.

How server verifies jwt token on server

To verify a JWT (JSON Web Token) on the server, the following steps are typically followed:

  1. Extract the Token: The server retrieves the JWT from the request, usually from the Authorization header as a Bearer token.

  2. Decode the Token: The server decodes the JWT to access its header and payload. This step does not require validation and can be done using a base64 decoding method.

  3. Verify the Signature: The most critical part of the verification process is to check the signature of the token:

    • The server uses the algorithm specified in the JWT header (e.g., HS256, RS256) and the secret key (for symmetric algorithms) or the public key (for asymmetric algorithms) that was used to sign the token.
    • It re-generates the signature using the header and payload and compares it with the signature part of the received token.
  4. Check Claims: The server validates the claims in the payload:

    • Expiration: Check the exp claim to see if the token is still valid.
    • Audience: Verify the aud claim to ensure the token was intended for your server.
    • Issuer: Check the iss claim to confirm it was issued by a trusted source.
    • Not Before: Optionally, check the nbf claim to see if the token is being used before its valid time.
  5. Process the Request: If the token is valid and all claims check out, the server processes the request. If not, it responds with an appropriate error (e.g., 401 Unauthorized).

Access token vs Refresh Token:

  1. Access Token (short-lived): This token is used for authenticating requests and is typically valid for a short duration (e.g., 15 minutes).
  2. Refresh Token (long-lived): This token is used to get a new access token when the old one expires. It typically has a longer expiry time (e.g., 7 days or more). 
What information JWT token contains

JWT Token Generation Code in C#
Click here

Claim in jwt authentication token
Click here

By following these steps, the server ensures that the JWT is valid, has not been tampered with, and is still active.


Reference: https://medium.com/https://www.c-sharpcorner.com/https://javascript.plainenglish.io/

Continue Reading →

Tuesday, 4 June 2019

ADFS | SSO Solution

Active Directory Federation Services (ADFS) is a Single Sign-On (SSO) solution created by Microsoft. As a component of Windows Server operating systems, it provides users with authenticated access to applications that are not capable of using Integrated Windows Authentication (IWA) through Active Directory (AD).

Developed to provide flexibility, ADFS gives organizations the ability to control their employees’ accounts while simplifying the user experience: employees only need to remember a single set of credentials to access multiple applications through SSO.

How does ADFS work?
ADFS manages authentication through a proxy service hosted between AD and the target application. It uses a Federated Trust, linking ADFS and the target application to grant access to users. This enables users to log onto the federated application through SSO without needing to authenticate their identity on application directly.

The authentication process generally follows these four steps:

  1. The user navigates to a URL provided by the ADFS service.
  2. The ADFS service then authenticates the user via the organization’s AD service.
  3. Upon authenticating, the ADFS service then provides the user with an authentication claim.
  4. The user’s browser then forwards this claim to the target application, which either grants or denies access based on the Federated Trust service created.

Why do companies use ADFS?

ADFS was born out of the need to overcome the authentication challenges created by AD in an increasingly connected online world. AD and IWA have set limitations when it comes to modern authentication, and cannot authenticate users accessing AD integrated applications externally. This is a challenge in the modern workplace, where users often need to access applications that are not owned or managed by their AD organization.

ADFS is able to resolve and simplify these third-party authentication challenges, but does come with certain risks and disadvantages.

ADFS solves the problem of users who need to access AD integrated applications while working remotely, offering a flexible solution whereby they can authenticate using their standard organizational AD credentials via a web interface. It allows users from one organization to access the applications of another organization beyond the realm of their AD domain. Examples include applications in a partner organization or modern cloud services, which now form part of many organizations’ extended IT landscape.

Over 90% of organizations use Active Directory, which means many use ADFS as well.

What are the risks and disadvantages?
ADFS does have its drawbacks, which make it far from an ideal authentication solution. These disadvantages include the hidden infrastructure and maintenance costs, as well as security risks.

Even though ADFS is a free feature on Windows Server, commissioning ADFS requires a Windows Server license and a server to host the ADFS service, which comes at a cost to the organization. Notably, the cost of a server license has increased since the release of Windows Server 2016, with licensing now based on a per core basis.

Hidden maintenance costs
Over and above the direct costs of commissioning ADFS, organizations also need to consider the ongoing operational costs of managing and maintaining an ADFS service. Trusts between AD domains need to be maintained by employees with deep technical skills and ADFS servers need to be patched, updated and backed up on a regular basis. In addition, since ADFS is a critical service, high availability is key. Depending on how it is configured, ADFS can cost more than anticipated: both directly as more infrastructure is required, and indirectly as complexity increases.

Overall complexity
Commissioning, configuring, and maintaining an ADFS solution is not a simple undertaking. Furthermore, each time an application is added to an ADFS service the process is time-consuming and technically intricate, which hinders IT agility.

Security risks
An out-of-the-box, standard install of ADFS is not as secure as it can be. In order to properly secure it, there are multiple steps that IT needs to perform. In addition, as ADFS runs on a Windows Server, that too needs to be hardened and secured to ensure the solution is not at risk.

ADFS vs. Cloud identity

There is no doubt ADFS does have some advantages that make it a popular choice for organizations looking for a federated identity solution. However, ADFS does have distinct disadvantages that cannot be ignored.

Third-party cloud-based identity services can possess features that match, and in some instances surpass, those of ADFS. Cloud identity solutions are more cost effective due to the lower operational overhead needed to run them; beyond that, they have built-in high availability and seamless integration with hundreds of applications. Okta provides secure cloud based identity solutions for its users—solutions that will not only solve authentication challenges, but that will also keep security consistently front-of-mind.

Continue Reading →

Tuesday, 6 March 2018

Web API 2- token based authentication

ASP.NET Web API can be accessed over Http by any client using the Http protocol. Typically, in a Line of Business (LOB) application, using Web API is a standard practice now-a-days. This framework enables data communication in JSON format (by default) and hence helps in lightweight communication.
  In token-based authentication (OWIN), you pass your credentials [user name and password], which go to authentication server. Server verifies your credentials and if it is a valid user then it will return a signed token to client system, which has expiration time. Client can store this token to locally using any mechanism like local storage, session storage etc. and if client makes any other call to server for data then it does not need to pass its credentials every time. Client can directly pass token to server, which will be validated by server and if token is valid then you will able to access your data.
How token based authentication actually works?
In the Token based approach, the client application first sends a request to Authentication server endpoint with an appropriate credential. Now If the username and password are found correct then the Authentication server send a token to the client as a response. This token contains enough data to identify a particular user and an expiry time.The client application then uses the token to access the restricted resources in next requests till the token is valid.

In this article, I have used Visual Studio 2015


1:- Create New Project.
Go to the file menu > create > projet > select "asp.net web application" under web > enter application name > select your project location > and then click on add button

    It will bring up a new dialog window for select template > here I will select empty template > and then checked MVC & Web API checkbox from Add folder and core references for > and then click on Ok button.

We are using OWIN [Open Web Interface for .Net] that is an interface between your web server and web application. So, it works as a middle ware in applications, which process your incoming request and validate it. Here we are using AuthServerProvider, which is nothing but a class which validate user based on their credentials. You can find this class below.

2: Add required references from NuGet packages into our application.
To Implement token based authentication in WEB API, we need to install followings references from NuGet packages
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Cors
for adding following resources from NuGet, Go to Solution Explorer >  Right Click on References > Click on Manage NuGet packages > Search for the Microsoft.Owin.Host.SystemWeb, Microsoft.Owin.Security.OAuth & Microsoft.Owin.Cors and install.

3: Add a class for validating user credentials asking for tokens.

add a class in our application for validate the credentials for users and generate token.

In this class we will inherit "OAuthAuthorizationServerProvider" class for  overriding 2 methods "ValidateClientAuthentication" and "GrantResourceOwnerCredentials".

"ValidateClientAuthentication" method is used for validating client app (for the sake of simplicity, we will  deep dive on "ValidateClientAuthentication" method later) and in the "GrantResourceOwnerCredentials"  method we will validate the credentials of users and if we found valid credential, we will generate the signed token, using which user can access authorized resources of server.

AuthServerProvider.cs
using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;

namespace WebApiTokenBasedAuth
{
    public class AuthServerProvider: OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated(); 
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            if (context.UserName == "admin" && context.Password == "admin")
            {
                identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
                identity.AddClaim(new Claim("username", "admin"));
                identity.AddClaim(new Claim(ClaimTypes.Name, "Suraj Mad. Admin"));
                context.Validated(identity);
            }
            else if (context.UserName == "user" && context.Password == "user")
            {
                identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
                identity.AddClaim(new Claim("username", "user"));
                identity.AddClaim(new Claim(ClaimTypes.Name, "Suraj Mad."));
                context.Validated(identity);
            }
            else
            {
                context.SetError("invalid_grant", "Provided username and password is incorrect");
                return;
            }
        }
    }
}

4: Add Owin Start Up class.

Now we will add OWIN Startup class. This is the startup class used to configure application startup.
It accepts IAppBuilder interface to manage middleware for the application. In this case it is OWIN. This function uses the OAuthAuthorizationServerOptions class which provides the information needed to control Authorization server middleware behavior. The code sets some properties for this class.
Go to Solution Explorer > Right Click on Project Name form Solution Explorer > Add > New Item > Select OWIN Startup class > Enter class name > Add.

Startup.cs
using System;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Security.OAuth;
using System.Web.Http;

[assembly: OwinStartup(typeof(WebApiTokenBasedAuth.Startup))]
namespace WebApiTokenBasedAuth
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //enable cors origin requests
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            var myProvider = new WebApiTokenBasedAuth.AuthServerProvider();
            OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = myProvider
            };
            app.UseOAuthAuthorizationServer(options);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

            HttpConfiguration config = new HttpConfiguration();
            WebApiConfig.Register(config);
        }
    }
}

In the above class we need the following important properties

· TokenEndPointPath - The client application communicates as part of the OAuth protocol. To complete the login with the token, /Token is used. The grant_type must be shared by the client to complete the login using access token generated by the server.

· AccessTokenExpirationTimeSpan - This is the time span for the life of the authorization token after being issued.

· Provider - The value for the property is set by the OAuthorizationServerProvider object. This class is responsible for providing behavior to requests. This is used to validate client authentication, claims etc.

AllowInsecureHttp - This is a Boolean property used to allow authorize and token requests to arrive on http URI address.

5: Add an another Class for override authorize attribute.

When building an HTTP REST API, we should use appropriate HTTP response codes to indicate the status of a response. I always use 401 and 403 status code for getting authentication/authorization status. 401 (Unauthorized) - indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. and 403 (Forbidden) - when the user is authenticated but isn’t authorized to perform the requested operation on the given resource.

Unfortunately, the ASP.NET MVC/Web API [Authorize] attribute doesn’t behave that way – it always emits 401. So, here in our Web API application, I am going to add a class for override this behavior. Here we will return 403 when the user is authenticated but not authorized to perform the requested operation.

AuthorizeAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApiTokenBasedAuth
{
    public class AuthorizeAttribute: System.Web.Http.AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(actionContext);
            }
            else
            {
                actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
            }
        }
    }
}

6: Add WEB API Controller. 
Add a WEB API Controller , Where we will add some action So we can check the token authentication is working fine or not.


7: Add an action for getting data from the server for all anonymous user.
I have added this action for all anonymous users. All type of request, whether it is authenticated or not can access this action.

        [AllowAnonymous]
        [HttpGet]
        [Route("api/MyWebApi/GetAll")]
        public IHttpActionResult Get()
        {
            return Ok("Now server time is: " + DateTime.Now.ToString());
        }

8: Add an another action for getting data from the server for all authenticated user.
I have added this action for all type of authenticated users, whether it is Admin user or normal user.

        [Authorize]
        [HttpGet]
        [Route("api/MyWebApi/authenticate")]
        public IHttpActionResult GetForAuthenticate()
        {
            var identity = (ClaimsIdentity)User.Identity;
            return Ok("Hello " + identity.Name);
        }

9: Add an another action for getting data from the server only for Admin user.
I have added this action only for Admin role type users.


        [Authorize(Roles = "admin")]
        [HttpGet]
        [Route("api/MyWebApi/authorize")]
        public IHttpActionResult GetForAdmin()
        {
            var identity = (ClaimsIdentity)User.Identity;
            var roles = identity.Claims
                        .Where(c => c.Type == ClaimTypes.Role)
                        .Select(c => c.Value);
            return Ok("Hello " + identity.Name + " Role: " + string.Join(",", roles.ToList()));
        }

10: Run Application.
Our WEB API Configuration is ready, Now we will test our application with POSTMAN

Postman is an extension of Chrome, which is used as a client application to test the request and response between web service and client.

Test 1:
Select GET (see below picture section 1),  Enter this url http://localhost:/api/MyWebApi/GetAll  and then click on send button.

We will get 200 OK status code (see section 3 in the below picture) and the result in the section 4 in that picture. That means our first action working fine when the request is anonymous.


But now if we try to access our 2nd action (GetForAuthenticate with url : http://localhost:52381/api/MyWebApi/authenticate) then we will get 401 Unauthenticated because the request is not authenticated yet. It will same for the 3rd action also.


So, what we need to access the 2nd and 3rd action? We need access token from server first and then we can access the 2nd and 3rd action with that access token.

Test 2 : Getting access token.
Select POST (in section 1),  Enter this URL http://localhost:/token (in section 2) and then click on body (in section 3) and select select x-www-form-urlencoded and then enter 3 parameter, 1. username (value : user) 2. password (value: user) and 3. grant_type (value: password) and then click on  send button. After click on send button we will get 200 OK (see section 4) and access token (see section 5)


Now we can access http://localhost:52381/api/MyWebApi/authenticate with that access token.

Test 3: Access restricted resource with access token.

Select GET(in section 1),  Enter this URL http://localhost:52381/api/MyWebApi/authenticate (in section 2) and then click on Headers(in section 3) and enter 1 parameter, Authorization (value : Bearer) and then click on  send button. After click on send button we will get 200 OK (see section 4) and the result (see section 5).

In the same way, we can access our 3rd action but we have to get token logged in with username : admin and password: admin because the 3rd action accessible only for Admin role user.

We have other machenish also for Authentication. click on below links for more.
  1. Basic Authentication https://www.freecodecamp.org/
  2. JWT Authentication https://www.c-sharpcorner.com/
Continue Reading →

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (47) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (55) CD (1) CI (2) CloudComputing (2) Coding (10) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (20) Entity Framework (5) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) jwtToken (4) Lamda (3) Linq (10) microservice (4) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (2) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives