Authentication Server using ASP.NET Core Web API

How to Implement Authentication Server using ASP.NET Core Web API:

In this article, I will discuss How to Implement the Authentication Server Application using ASP.NET Core Web API. Please read our previous article discussing the basic concepts of SSO Authentication. This is the First Application of SSO Implementation.

Authentication Server Application using ASP.NET Core Web API

Now, we will implement an authentication server application using ASP.NET Core Web API, ASP.NET Core Identity, JWT (JSON Web Token), and Entity Framework Core with SQL Server database. So, we will build the project using ASP.NET Core Web API along with several key technologies:

  • ASP.NET Core Identity: Provides user management features (registration, login, roles, etc.).
  • JWT (JSON Web Tokens): Used to generate secure tokens for authenticating users.
  • Entity Framework Core (EF Core): Handles database interactions with SQL Server database.
  • SSO (Single Sign-On) Mechanism: This enables a user to authenticate once and then use a special token (SSO token) to access multiple systems without re-entering credentials.

This Authentication Server will handle essential security operations such as User Registration, Login, SSO Token Generation, and SSO Token Validation, which are fundamental to Single Sign-On (SSO) authentication.

User Registration:

User registration is the process by which a new user creates an account in the authentication system. This involves submitting a username, email, and password securely stored in the database. In our example, ASP.NET Core Identity handles creating and storing the user record in the database.

User Login:

User login allows registered users to authenticate by providing their username and password. If the credentials are correct, the system generates a JWT token and returns it to the client. This JWT token allows users to access protected endpoints without re-authenticating on every request.

SSO Token Generation:

After a successful login, Single Sign-On (SSO) allows users to log in once and access multiple services without re-authenticating. The server generates a unique SSO token (typically a GUID) stored in the database along with metadata like expiry time and usage status. This SSO token can be used to obtain a new JWT token to access other services.

SSO Token Validation:

When a client presents an SSO token, the server checks if:

  • The token exists.
  • It hasn’t already been used.
  • It has not expired.

If the token passes all these checks, it is marked as used, and a new JWT token is generated for the client to use.

Creating a New Project and Adding Necessary NuGet Packages

Open Visual Studio and create a new ASP.NET Core Web API project named AuthenticationServer. Once you create the Project, please add the following NuGet packages, which are required for Entity Framework Core with SQL Server Database, Identity Setup, and JWT Authentication.

  • Microsoft.EntityFrameworkCore.SqlServer: Enables EF Core to work with SQL Server.
  • Microsoft.EntityFrameworkCore.Tools: Provides command-line tools for EF Core (e.g., migrations).
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore: Integrates ASP.NET Core Identity with Entity Framework Core.
  • Microsoft.AspNetCore.Authentication.JwtBearer: Supports JWT Bearer token authentication.

You can add these Package using NuGet Package Managers for Solution or by executing the following code in Visual Studio Package Manager Console:

  • Install-Package Microsoft.EntityFrameworkCore.SqlServer
  • Install-Package Microsoft.EntityFrameworkCore.Tools
  • Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore
  • Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
Creating SSO Token Model:

By default, ASP.NET Core Identity provides the required models for membership management. However, it does not provide any model for SSO Token management. So, we need a database table to manage the SSO Token.

First, create the Models folder in the project root directory. Then, create a class file named SSOToken.cs within the Models folder and copy and paste the following code. We will create a database table for this model to store the UserId and the SSO Token, determine whether the Token was already used and when the Token will expired, and determine if it has already expired.

namespace AuthenticationServer.Models
{
    public class SSOToken
    {
        public int Id { get; set; }                  // Primary key for the SSOToken record.
        public string UserId { get; set; }           // Associates the token with a specific user.
        public string Token { get; set; }            // The unique SSO token string (usually a GUID).
        public DateTime ExpiryDate { get; set; }     // The date and time after which the token becomes invalid.
        public bool IsUsed { get; set; }             // Indicates whether the token has already been used.
        public bool IsExpired => DateTime.UtcNow > ExpiryDate; // Computed property to check if the token is expired.
    }
}
Explanation of Each Property (Regarding SSO):
  • Id: A unique identifier for each SSO token record in the database.
  • UserId: Links the SSO token to the user who requested it. This allows the system to know which user the token is associated with.
  • Token: The token string generated (using a GUID) to identify the SSO request uniquely.
  • ExpiryDate: Sets a time limit for the token’s validity (e.g., 10 minutes from generation). Once the current time exceeds this date, the token should no longer be accepted.
  • IsUsed: A flag that tracks whether the token has already been used. SSO tokens are often designed for one-time use to enhance security.
  • IsExpired: A read-only property that dynamically checks if the current UTC is later than the expiry date, indicating that the token is no longer valid.
Define Database Context Class

Next, we need to define the Context class for Entity Framework Core. The Context class must be inherited from the IdentityDbContext class instead of the DbContext class. This is required because IdentityDbContext provides all the DbSet properties needed to manage the identity tables in SQL Server.

Also, we need to include the SSOToken model as a DbSet property for which we want to create the SSOTokens table in the database. So, first, create a folder named Data, and inside the Data folder, create a class file named ApplicationDbContext.cs and then copy and paste the following code:

using AuthenticationServer.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

namespace AuthenticationServer.Data
{
    // The ApplicationDbContext class extends IdentityDbContext, which manages user authentication-related entities.
    // IdentityDbContext<IdentityUser> provides all the necessary tables for authentication, such as AspNetUsers, AspNetRoles, etc.
    public class ApplicationDbContext : IdentityDbContext<IdentityUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
            // The constructor doesn't need any custom logic here, so it's empty.
        }

        // This property defines a DbSet<SSOToken> representing the SSOTokens table in the database.
        public DbSet<SSOToken> SSOTokens { get; set; }
    }
}

Here

  • IdentityDbContext: By inheriting from this class, you automatically include tables such as AspNetUsers and AspNetRoles needed for user management.
  • DbSet<SSOToken> SSOTokens: This property tells EF Core to create and manage a table for the SSOToken model. This is where SSO token details are stored.
Configuring Connection String and JWT Keys in AppSettings.json file:

Next, open the AppSettings.json file and copy and paste the following code. Here, we are providing the connection string key name as AuthenticationServerDBConnection, and we have also set the JWT key, which we will use in our Program class to generate and validate the JWT Token.

{
  "ConnectionStrings": {
    "AuthenticationServerDBConnection": "Server=LAPTOP-6P5NK25R\\SQLSERVER2022DEV;Database=AuthenticationServerDB;Trusted_Connection=True;TrustServerCertificate=True;"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },

  "Jwt": {
    "Key": "KHPK6Ucf/zjvU4qW8/vkuuGLHeIo0l9ACJiTaAPLKbk=", //Secret Key
    "Issuer": "https://localhost:7035", //Authentication Server Domain URL Base Address
    "Audience": "http://localhost:7035" //Client Application Domain URL Base Address
  },

  "AllowedHosts": "*"
}
Configure Services in the Program.cs

Next, we need to configure the required Services in the Program.cs class file. Here, we need to configure the services for EF Core, Identity, JWT, Authentication Schema, etc. The following code is self-explained, so please read the comment lines for a better understanding.

using AuthenticationServer.Data;
using AuthenticationServer.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace AuthenticationServer
{
    public class Program
    {
        // Entry point for the application
        public static void Main(string[] args)
        {
            // Creating the builder for configuring the app and services.
            var builder = WebApplication.CreateBuilder(args);

            // Adds support for controllers to the application.
            builder.Services.AddControllers()
                .AddJsonOptions(options =>
                {
                    // Configuring JSON serialization options.
                    options.JsonSerializerOptions.PropertyNamingPolicy = null;
                });

            // Add services to the container.
            // Configures the ApplicationDbContext to use SQL Server with the connection string from the configuration file.
            builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(builder.Configuration.GetConnectionString("AuthenticationServerDBConnection")));

            // Adding ASP.NET Core Identity services, which provide user authentication and role-based authorization.
            builder.Services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            // Adding and configuring authentication to use JWT Bearer tokens.
            // This sets JWT Bearer as the default authentication scheme and challenge scheme.
            builder.Services.AddAuthentication(options =>
            {
                //Default Authentication Scheme
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

                //Default Authorization Scheme
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            // Adding the JwtBearer authentication handler to validate incoming JWT tokens.
            .AddJwtBearer(options =>
            {
                // Configuring the parameters for JWT token validation.
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false, // Ensure the token's issuer matches the expected issuer.
                    ValidateAudience = false, // Ensure the token's audience matches the expected audience.
                    ValidateLifetime = true, // Validate that the token has not expired.
                    ValidateIssuerSigningKey = true, // Ensure the token is signed by a trusted signing key.
                    ValidIssuer = builder.Configuration["Jwt:Issuer"], // The expected issuer, retrieved from configuration (appsettings.json).
                    ValidAudience = builder.Configuration["Jwt:Audience"], // The expected audience, retrieved from configuration (appsettings.json).
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) // The symmetric key used to sign the JWT, also from configuration.
                };
            });

            // Adds support for automatically generating Swagger/OpenAPI documentation.
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            // Build the application and return a fully configured app instance.
            var app = builder.Build();

            // Configuring the HTTP request pipeline (middleware components).
            // If the environment is development, enable Swagger UI for testing and documentation.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger(); // Enable middleware to serve the generated Swagger as JSON endpoint.
                app.UseSwaggerUI(); // Enable the Swagger UI in the browser for testing the API.
            }

            // Enforce the use of HTTPS (secure communication) for incoming requests.
            app.UseHttpsRedirection();

            // Enable authentication middleware to validate the JWT and set the user principal.
            app.UseAuthentication();

            // Enable authorization middleware to enforce policies based on the authenticated user's identity.
            app.UseAuthorization();

            // Map controllers to the appropriate endpoints.
            // This routes incoming requests to the appropriate controller/action based on the URL.
            app.MapControllers();

            // Start the application and begin listening for incoming HTTP requests.
            app.Run();
        }
    }
}
Explanation of Key Concepts:
  • DbContext Configuration: Sets up the database connection and ensures the Entity Framework Core interacts with SQL Server.
  • Identity: Provides user management and authentication services, storing users and roles in the database using Entity Framework Core.
  • JWT Bearer Authentication: Configures the app to use JWT tokens for authentication and authorization, ensuring each request carries a valid token.
  • Swagger: Provides auto-generated API documentation and testing tools that are accessible via a browser.
  • Middleware Pipeline: Configures the middleware components that handle HTTP requests, including HTTPS redirection, authentication, authorization, and routing to controllers.
Creating DTOs:

Next, we need to create the DTOs required for exchanging the data between client and server. DTOs are used to transfer data between the client and the server. They help encapsulate only the necessary data for each operation. So, first, create a folder named DTOs in the project root directory and then add the following DTOs.

RegisterDTO

Create a class file named RegisterDTO.cs within the DTOs folder, and then copy and paste the following code. This DTO facilitates user registration by encapsulating the necessary information (username, email, and password) in a structured format. This allows the registration endpoint to receive and validate data cleanly.

using System.ComponentModel.DataAnnotations;

namespace AuthenticationServer.DTOs
{
    public class RegisterDTO
    {
        [Required(ErrorMessage = "Username is Required")]
        public string Username { get; set; }

        [EmailAddress(ErrorMessage = "Please provide a valid Email")]
        [Required(ErrorMessage = "Email is Required")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Password is Required")]
        public string Password { get; set; }
    }
}
LoginDTO

Create a class file named LoginDTO.cs within the DTOs folder, and then copy and paste the following code. This DTO provides a straightforward way to pass the username and password when logging in. It ensures these fields are always included and properly validated.

using System.ComponentModel.DataAnnotations;

namespace AuthenticationServer.DTOs
{
    public class LoginDTO
    {
        [Required(ErrorMessage = "Username is Required")]
        public string Username { get; set; }

        [Required(ErrorMessage = "Password is Required")]
        public string Password { get; set; }
    }
}
LoginResponseDTO

Create a class file named LoginResponseDTO.cs within the DTOs folder and then copy and paste the following code. This DTO returns the authentication result (e.g., a JWT token) in a clear and predictable structure after a successful login.

namespace AuthenticationServer.DTOs
{
    public class LoginResponseDTO
    {
        public string Token { get; set; }
    }
}
SSOTokenResponseDTO

Create a class file named SSOTokenResponseDTO.cs within the DTOs folder and then copy and paste the following code. This DTO returns the generated SSO token in a standardized format, making it easier for the client to handle the response.

namespace AuthenticationServer.DTOs
{
    public class SSOTokenResponseDTO
    {
        public string SSOToken { get; set; }
    }
}
ValidateSSOTokenRequestDTO

Create a class file named ValidateSSOTokenRequestDTO.cs within the DTOs folder and then copy and paste the following code. This DTO encapsulates the SSO token that the server needs to validate. The endpoint clearly knows what to expect from the request by having a dedicated DTO.

using System.ComponentModel.DataAnnotations;

namespace AuthenticationServer.DTOs
{
    public class ValidateSSOTokenRequesDTO
    {
        [Required(ErrorMessage = "SSOToken is Required")]
        public string SSOToken { get; set; }
    }
}
ValidateSSOTokenResponseDTO

Create a class file named ValidateSSOTokenResponseDTO.cs within the DTOs folder and then copy and paste the following code. This DTO provides both a new JWT token and user details after successful SSO token validation. This DTO ensures the client gets all the information it needs in a single response.

namespace AuthenticationServer.DTOs
{
    public class ValidateSSOTokenResponseDTO
    {
        public string Token { get; set; }
        public UserDetails UserDetails { get; set; }
    }

    public class UserDetails
    {
        public string UserId { get; set; }
        public string? Username { get; set; }
        public string? Email { get; set; }
    }
}
Creating Authentication Controller:

Next, create a new API Empty Controller named AuthenticationController within the Controllers folder and then copy and paste the following code. The following controller provides the endpoints for User Registration, Login, SSO Token Generation, and Validation. The following code is self-explained, so please read the comment lines for a better understanding.

using AuthenticationServer.Data;
using AuthenticationServer.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using AuthenticationServer.DTOs;

namespace AuthenticationServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        private readonly UserManager<IdentityUser> _userManager;
        private readonly ApplicationDbContext _context;
        private readonly IConfiguration _configuration;

        // Constructor to inject the required services:
        // UserManager, ApplicationDbContext, IConfiguration
        public AuthenticationController(
            UserManager<IdentityUser> userManager,
            ApplicationDbContext context,
            IConfiguration configuration)
        {
            _userManager = userManager;
            _context = context;
            _configuration = configuration;
        }

        // POST: api/Authentication/Register
        [HttpPost("Register")]
        [AllowAnonymous]
        public async Task<IActionResult> Register([FromBody] RegisterDTO dto)
        {
            // Create a new IdentityUser based on the incoming model data
            var user = new IdentityUser
            {
                UserName = dto.Username,
                Email = dto.Email
            };

            // Create the user in the identity system
            var result = await _userManager.CreateAsync(user, dto.Password);

            // If creation succeeded, return a success message
            if (result.Succeeded)
            {
                return Ok(new { Result = "User Registered Successfully" });
            }

            // If creation failed, return the validation errors
            return BadRequest(result.Errors);
        }

        // POST: api/Authentication/login
        [HttpPost("Login")]
        [AllowAnonymous]
        public async Task<ActionResult<LoginResponseDTO>> Login([FromBody] LoginDTO dto)
        {
            // Find the user based on the username
            var user = await _userManager.FindByNameAsync(dto.Username);

            // Validate the user's credentials
            if (user != null && await _userManager.CheckPasswordAsync(user, dto.Password))
            {
                // Generate the JWT token and return it
                var token = GenerateJwtToken(user);

                LoginResponseDTO loginResponseDTO = new LoginResponseDTO()
                {
                    Token = token,
                };

                return Ok(loginResponseDTO);
            }

            // If authentication fails, return an unauthorized response
            return Unauthorized("Invalid username or password");
        }

        // POST: api/Authentication/GenerateSSOToken
        [HttpPost("GenerateSSOToken")]
        [Authorize] // Ensures that the user is authenticated
        public async Task<ActionResult<SSOTokenResponseDTO>> GenerateSSOToken()
        {
            try
            {
                // Get the UserId from the JWT Token Claims
                var UserId = User.FindFirstValue("User_Id");

                if (UserId == null)
                {
                    return NotFound("Invalid token");
                }

                // Fetch the user from the database using the UserId
                var user = await _userManager.FindByIdAsync(UserId);

                // Check if the user exists
                if (user == null)
                {
                    return NotFound("User not found");
                }

                // Create a new SSO token and add it to the database
                var ssoToken = new SSOToken
                {
                    UserId = user.Id,
                    Token = Guid.NewGuid().ToString(), // Generate a unique SSO token
                    ExpiryDate = DateTime.UtcNow.AddMinutes(10), // Set an expiration time for the token
                    IsUsed = false
                };

                // Add the token to the database
                _context.SSOTokens.Add(ssoToken);
                await _context.SaveChangesAsync();

                SSOTokenResponseDTO ssoTokenResponseDTO = new SSOTokenResponseDTO()
                {
                    SSOToken = ssoToken.Token
                };

                // Return the newly created SSO token
                return Ok(ssoTokenResponseDTO);
            }
            catch (Exception ex)
            {
                // Handle any exceptions that occur and return a server error response
                return StatusCode(500, $"Internal server error: {ex.Message}");
            }
        }

        // POST: api/Authentication/ValidateSSOToken
        [HttpPost("ValidateSSOToken")]
        [AllowAnonymous]
        public async Task<ActionResult<ValidateSSOTokenResponseDTO>> ValidateSSOToken([FromBody] ValidateSSOTokenRequesDTO request)
        {
            try
            {
                // Fetch the SSO token from the database
                var ssoToken = await _context.SSOTokens.FirstOrDefaultAsync(t => t.Token == request.SSOToken);

                // Check if the token is valid (exists, not used, not expired)
                if (ssoToken == null || ssoToken.IsUsed || ssoToken.IsExpired)
                {
                    return BadRequest("Invalid or expired SSO token");
                }

                // Mark the token as used
                ssoToken.IsUsed = true;
                await _context.SaveChangesAsync();

                // Find the user associated with the SSO token
                var user = await _userManager.FindByIdAsync(ssoToken.UserId);

                if (user == null)
                {
                    return BadRequest("Invalid User");
                }

                // Generate a new JWT
                var newJwtToken = GenerateJwtToken(user);

                // Return the new JWT token along with user details (e.g., username and email)
                ValidateSSOTokenResponseDTO validateSSOTokenResponseDTO = new ValidateSSOTokenResponseDTO()
                {
                    Token = newJwtToken,
                    UserDetails = new UserDetails()
                    {
                        UserId = user.Id,
                        Email = user.Email,
                        Username = user.UserName
                    }
                };

                return Ok(validateSSOTokenResponseDTO);
            }
            catch (Exception ex)
            {
                // Handle exceptions and return a server error response
                return StatusCode(500, $"Internal server error: {ex.Message}");
            }
        }

        // Helper method to generate a JWT token for the authenticated user
        private string GenerateJwtToken(IdentityUser user)
        {
            // Defines a set of claims to be included in the token.
            var claims = new List<Claim>
            {
                // Custom claim using the user's ID.
                new Claim("User_Id", user.Id.ToString()),
                
                // Standard claim for user identifier, using username.
                new Claim(ClaimTypes.NameIdentifier, user.UserName),
                
                // Standard claim for user's email.
                new Claim(ClaimTypes.Email, user.Email),
                
                // Standard JWT claim for subject, using user ID.
                new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString())
            };

            // Get the symmetric key from the configuration and create signing credentials
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            // Create the JWT token
            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.UtcNow.AddMinutes(30), // Token expiration time
                signingCredentials: creds);

            // Serialize the token and return it as a string
            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}
Authentication Controller Endpoints

The AuthenticationController contains endpoints that handle the authentication flows. The following are the endpoints:

  • Register Endpoint: This endpoint Receives registration data via a RegisterDTO, creates a new user using ASP.NET Core Identity, and returns a success or error response.
  • Login Endpoint: This endpoint accepts login credentials via a LoginDTO, validates the user’s identity, and, if successful, returns a LoginResponseDTO containing a JWT token. This token is used to authenticate subsequent requests.
  • Generate SSO Token Endpoint: This endpoint extracts the authenticated user’s ID from the JWT claims, generates a unique SSO token (with an expiration time of 10 minutes and marked as unused), saves it to the database, and returns it to the client in an SSOTokenResponseDTO.
  • Validate SSO Token Endpoint: This endpoint accepts an SSO token via a ValidateSSOTokenDTO. It checks whether the token exists, has not expired, and has not been used. If valid, it marks the token as used, retrieves the associated user, generates a new JWT token, and returns it along with user details (wrapped in a ValidateSSOTokenResponseDTO).
Migration and Database Update

Next, we need to generate the Migration and update the database. So, open the Package Manager Console and Execute the Add-Migration and Update-Database commands. You can give your migration any name. Here, I am giving it IdentityMigration1. The name you are giving it should not be given earlier.

Authentication Server using ASP.NET Core Web API

With this, the database and the tables must be created in the SQL Server Database, as shown in the image below. You can also see that the SSOTokens table generates the Framework along with the Identity tables.

How to Implement Authentication Server using ASP.NET Core Web API

Testing the Registration Endpoint

Endpoint: /api/Authentication/ Register
Method: POST
Request Body:

{
  "Username": "Pranaya",
  "Email": "Pranaya@Example.com",
  "Password": "Test@1234"
}

Expected Response:
If successful, you will receive a 200 OK response with the message:

Testing the Registration Endpoint

Testing the Login Endpoint

Endpoint: /api/Authentication/Login
Method: POST
Request Body:

{
  "Username": "Pranaya",
  "Password": "Test@1234"
}

Expected Response:
On success, you should receive a 200 OK response with a JWT token:

Testing the Login Endpoint

Testing the Generate SSO Token Endpoint

Method: POST
Request Header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJQcmFuYXlhIiwianRpIjoiMWFmZWI5NjItNThiZi00MjUyLTkxYjktY2M4OWE0MThmYzc4IiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiJhMWYyOTg3OS00YmYxLTQ1NTQtODY2OC03MTJlOThhYzNmOGEiLCJleHAiOjE3MjQ0NzgyNzEsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjcwMzUiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjcwMzUifQ.9U9_sHnhMztzcN1QdzhhXQObkKULQuScYOyASpIhFJI
Expected Response:
On success, you should receive a 200 OK response with the generated SSO token:

Testing the Generate SSO Token Endpoint

Testing the Validate SSO Token Endpoint

Endpoint: /api/Authentication/ValidateSSOToken
Method: POST
Request Body Example:

{
    "SSOToken": "9d813b1f-569c-4e86-8e3c-554c0198b2cd"
}

Expected Response:
On success, you should receive a 200 OK response with a new JWT token:

Testing the Validate SSO Token Endpoint

That’s it. We are done with our Authentication Server Implementation using ASP.NET Core Web API, ASP.NET Core Identity, and Entity Framework Core with SQL Server Database. In the next article, I will discuss How to Implement the Resource Server using ASP.NET Core Web API. I hope you enjoy this article on how to implement the authentication server using ASP.NET Core Web API.

Leave a Reply

Your email address will not be published. Required fields are marked *