Skip to main content

JWT Authentication (ASP.NET Core + Angular) - Backend


 Key code Snippet are followings

Back End:

Startup.cs

    public class Startup

    {

        public Startup(IConfiguration configuration)

        {

            Configuration = configuration;

        }


        public IConfiguration Configuration { get; }


        // This method gets called by the runtime. Use this method to add services to the container.

        public void ConfigureServices(IServiceCollection services)

        {

            services.AddDbContext<PharmaDbContext>(options =>

                        options.UseSqlServer(Configuration.GetConnectionString("DBConnection")));


            services.AddControllers();

            services.AddSwaggerGen(c =>

            {

                c.SwaggerDoc("v1", new OpenApiInfo { Title = "PharmaSuite", Version = "v1" });

            });


            services.ConfigureMappings();

            services.ConfigureBusinessServices(Configuration);

            services.ConfigureRepositories(Configuration);

            services.AddCors();

            services.AddHttpContextAccessor();


            // Configure Authentication


            var jwtSettings = Configuration.GetSection("JWTSettings")

                                                     .Get<JWTSettings>();


            services.AddAuthentication(auth =>

            {

                auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

                auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            })

            .AddJwtBearer(options =>

            {

                options.SaveToken = true;

                options.TokenValidationParameters = new TokenValidationParameters

                {

                    ValidateIssuer = true,

                    ValidIssuer = jwtSettings.Issuer,

                    ValidateAudience = true,

                    ValidAudience = jwtSettings.Audience,

                    ValidateIssuerSigningKey = true,

                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Secret))

                };

            });



        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

        {

            if (env.IsDevelopment())

            {

                app.UseDeveloperExceptionPage();

                app.UseSwagger();

                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "PharmaSuite v1"));

            }


           


            app.UseHttpsRedirection();


            app.UseRouting();


            // global cors policy

            app.UseCors(x => x

                .AllowAnyMethod()

                .AllowAnyHeader()

                .SetIsOriginAllowed(origin => true) // allow any origin

                .AllowCredentials()); // allow credentials


            HttpContextHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());


            app.UseAuthentication();

            app.UseAuthorization();


            app.UseEndpoints(endpoints =>

            {

                endpoints.MapControllers();

            });



        }

    }

}


.csproj: Nuget  package for JWT
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.6" />
    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.7.1" />


namespace PharmaSuite.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : BaseController
    {
        private readonly IUserService _userService;
        private readonly IConfiguration _configuration;
        public AccountController(IUserService userService, IConfiguration configuration)
        {
            _userService = userService;
            _configuration = configuration;
        }

        [AllowAnonymous]
        [HttpPost]
        [Route("Authenticate")]
        public async Task<IActionResult> Authenticate(UserLogin userLogin)
        {
            var candidate = await _userService.AuthenticateUser(userLogin);

            if (candidate != null)
            {
                var loginUser = await _userService.GetUserAsync(candidate.Id);

                var claims = new List<Claim>();
                claims.Add(new Claim("UserName", loginUser.UserName));
                claims.Add(new Claim("Email", loginUser.Email));
                claims.Add(new Claim("UserType", loginUser.UserType));
                claims.Add(new Claim("CompanyId", loginUser.CompanyId.ToString()));
                claims.Add(new Claim("UserId", loginUser.Id.ToString()));

                // Add roles as multiple claims
                foreach (var role in loginUser.Roles)
                {
                    claims.Add(new Claim(ClaimTypes.Role, role.Name));
                }

                var jwtSettings = _configuration.GetSection("JWTSettings")
                                         .Get<JWTSettings>();

                var token = JwtHelper.GetJwtToken(
                                loginUser.UserName,
                                jwtSettings.Secret,
                                jwtSettings.Issuer,
                                jwtSettings.Audience,
                                TimeSpan.FromMinutes(jwtSettings.TokenTimeoutMinutes),
                                claims.ToArray());

                var response = new TokenResponse()
                {
                    AccessToken = new JwtSecurityTokenHandler().WriteToken(token),
                    ExpiresOnUtc = token.ValidTo,
                    RoutePermissions = loginUser.RoutePermissions
                };

                return Ok(response);
            }
            else
            {
                return Unauthorized("Invalid Login Credentials!");
            }
        }

    }
}


TokenResponse Model:
public class TokenResponse
    {
        public string AccessToken { get; set; }
        public DateTime ExpiresOnUtc { get; set; }
        public List<UserRoutePermission> RoutePermissions { get; set; }
    }

JwtHelper : 

namespace PharmaSuite.Common.Helpers
{
    public class JwtHelper
    {
        public static JwtSecurityToken GetJwtToken(
        string username,
        string signingKey,
        string issuer,
        string audience,
        TimeSpan expiration,
        Claim[] additionalClaims = null)
        {
            var claims = new[]
            {
            new Claim(JwtRegisteredClaimNames.Sub,username),
            // this guarantees the token is unique
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

            if (additionalClaims is object)
            {
                var claimList = new List<Claim>(claims);
                claimList.AddRange(additionalClaims);
                claims = claimList.ToArray();
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            return new JwtSecurityToken(
                issuer: issuer,
                audience: audience,
                expires: DateTime.UtcNow.Add(expiration),
                claims: claims,
                signingCredentials: creds
            );
        }
    }
}

HttpContextHelper:

namespace PharmaSuite.Common.Helpers
{
    public static class HttpContextHelper
    {
        private static IHttpContextAccessor _httpContextAccessor;

        public static void Configure(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public static HttpContext HttpContext => _httpContextAccessor.HttpContext;
    }
}


BaseController:
namespace PharmaSuite.Controllers
{
    [ApiController]
    public class BaseController : ControllerBase
    {
       public CurrentUser CurrentUser { get { return this.currentUser; } }
       private CurrentUser currentUser = null;

        public BaseController()
        {
            
                var identity = HttpContextHelper.HttpContext.User.Identity as ClaimsIdentity;

                if (identity != null && identity.Claims != null && identity.Claims.Any())
                {
                    currentUser = new CurrentUser();

                    currentUser.UserId = Convert.ToInt32(identity.FindFirst("UserId").Value);
                    currentUser.CompanyId = Convert.ToInt32(identity.FindFirst("CompanyId").Value);
                    currentUser.UserType = identity.FindFirst("UserType").Value;
                    currentUser.UserName = identity.FindFirst("UserName").Value;
                    currentUser.Email = identity.FindFirst("Email").Value;
                }

        }
    }
}

Comments

Popular posts from this blog

update your package-lock.json according to what you have specified in the package.json file

  The objective of the   npm update   command is to update your   package-lock.json   according to what you have specified in the   package.json   file. This is the normal behavior. If you want to update your package.json file, you can use  npm-check-updates :  npm install -g npm-check-updates . You can then use these commands: ncu  Checks for updates from the package.json file ncu -u  Update the package.json file npm update --save  Update your package-lock.json file from the package.json file

FTP(File Transfer Protocol ) configuration and testing in Windows Server 2008 R2

First of all you have to know  what the FTP is " File Transfer Protocol ( FTP ) is a standard network protocol used to transfer files from one host or to another host over a TCP -based network". FTP Installation & Configuration: Step 1: Install the Web Server role with the IIS Management Console and FTP Server role services: Step 2: Add a new FTP Site Step 3: Setup the site with the default bindings and choose Allow SSL to avoid deploying a certificate:     Step 4: Configure user permissions and basic or anonymous permission. If your server is connected to your domain you can specify domain users, otherwise they must be local user accounts: Note: Finally you’ll have to configure your server’s firewall rules to allow access.Disregard any existing FTP firewall rules; although they should be enabled, they don’t actually allow access! Run Allow a Program Through Windows Firewall and grant access to C:\Windows\System32\svchost.exe T...