Sunday 29 January 2023

Angular authentication

Here I am providing only code snippet, required for angular authentication. If you are angular guy then you will understand the code easily and use in your application.

I have a User Model. Below is the code.

1- Creating user model

export class User {
    isAuth = false;
    userId: string;
    email: string;
    password: string;
    name: string;
    address: string;
    role: string;
    roles = [];
    token: string;
    contact: string;
    createdDate: any;
    updatedDate: any;
    costructor() { }
}


Environment.ts file code snippet.

export const environment = {
  production: false,
  apiAddress: 'http://localhost:1300/api',
}



2- Creating AuthService

First we will create a Auth service in Angular. Below is the code for AuthService.

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { UserLogin } from '../public/models/userLogin';
import { Observable } from 'rxjs/Rx';

import { User } from '../models/user';
import { environment as env } from '../../environments/environment';

declare const localStorage: any;

@Injectable()
export class AuthService {
    headers: Headers;
    user: User;
    constructor(private http: Http) {
        this.headers = new Headers({ 'content-type': 'application/json' });
        this.loadAuthUser();
    }
    loadAuthUser() {
      if (localStorage['authInfo'] !== undefined && localStorage['authInfo'] !== null) {
            this.user = JSON.parse(localStorage['authInfo']);
      }
    }
    SignOut() {
        localStorage.removeItem('authInfo');
        this.user = undefined;
    }
    setAuthUser(user: User) {
        localStorage['authInfo'] = JSON.stringify(user);
        this.user = user;
    }
    ValidateUser(user: UserLogin): Observable<User> {
        return this.http.post(env.apiAddress + '/auth', JSON.stringify(user),
            { headers: this.headers }).map((res) => {
                return res.json();
            }).catch((err) => Observable.throw(err));
    }
}


3- Creating LoginComponent code

Then We will call Login function for user authentication and token storage. Below is the code for Login Component.

import { Component, OnInit } from '@angular/core';
import { UserLogin } from '../models/userLogin';
import { AuthService } from '../../services/auth.service';
import { User } from '../../models/user';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styles: []
})
export class LoginComponent implements OnInit {
  user: UserLogin;
  ref = '';
  constructor(private authService: AuthService, private router: Router,
                                                    private route: ActivatedRoute) {
    this.user = new UserLogin();
  }

  ngOnInit() {  
    this.route.queryParams.subscribe((params) => {
      this.ref = params.ref;
    });
  }
  Login() {
    this.authService.ValidateUser(this.user).subscribe((res) => {
      const authObj: User = res;
      if (authObj.email !== '') {
        authObj.isAuth = true;
        this.authService.setAuthUser(authObj);
        if (this.ref !== undefined && this.ref !== '') {
          this.router.navigate([this.ref]);
        }
        else {
          if (authObj.roles.indexOf('Admin') > -1) {
            this.router.navigate(['admin']);
          } else {
            this.router.navigate(['user']);
          }
        }
      }
    });
  }
}


4- Creating AppRouting file 

Below is the Code of app.routing.ts file.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminAuthGuard, UserAuthGuard } from './services/auth.guard';

const routes: Routes = [
    { path: '', loadChildren: 'app/public/public.module#PublicModule' },
    { path: 'user', loadChildren: 'app/user/user.module#UserModule',
                                                    canActivate:[UserAuthGuard] },
    { path: 'admin', loadChildren: 'app/admin/admin.module#AdminModule',
                                                    canActivate: [AdminAuthGuard] }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
})
export class AppRoutingModule { }


5- Creating Route Guard file 

Below is the code of auth.guard.ts file.

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class AdminAuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) { }
  canActivate() {
    if (!(this.authService.user != null && this.authService.user.isAuth)) {
      this.router.navigate(['login']);
      return false;
    } else if (this.authService.user.roles.indexOf('Admin') > -1) {
      return true;
    } else {
      this.router.navigate(['unauthorize']);
      return false;
    }
  }
}

@Injectable()
export class UserAuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) { }
  canActivate() {
    if (!(this.authService.user != null && this.authService.user.isAuth)) {
      this.router.navigate(['login']);
      return false;
    } else if (this.authService.user.roles.indexOf('User') > -1) {
      return true;
    } else {
      this.router.navigate(['unauthorize']);
      return false;
    }
  }
}

Creating Sign-out feature 

Below is the code snippet from a component.

  ...
    <ul class="nav navbar-nav pull-right" *ngIf="authService.user!=undefined">
      <li style="padding: 15px;">
        Welcome : {{authService.user.name}}
      </li>
      <li>
        <a href="javascript:void(0)" (click)="signout()">SignOut</a>
      </li>
    </ul> ...


  ...       constructor(public authService: AuthService, private router: Router) { }
      signout() {
        this.authService.SignOut();
        this.router.navigate(['/login']);
      }     ...

Sending token value in Request header- 

1- Using Http-Interceptors

2- Using RequestOptions (below is example code snippet)

@Injectable()
export class ProductService {
  private baseUrl = '';
  private headers: any;
  private options;
  constructor(private http: Http, private authService: AuthService) {
    this.options = new RequestOptions({     headers: new Headers({                           'authorization': this.authService.user.token,
                          'Content-Type': 'application/json'
                         })
    });
    this.baseUrl = env.apiAddress;
  }

  getAll(): Observable<Product[]> {
    return this.http.get(`${this.baseUrl}/product`, this.options)
      .map((res: Response) => res.json())
      .catch((error: any) => Observable.throw(error.json().error || 'Server error'));
  }
  add(product: Product): Observable<Response> {
    return this.http
      .post(`${this.baseUrl}/product`, JSON.stringify(product), this.options)
      .catch((error: any) => Observable.throw('Server error'));
  }
    .......         ......


Continue Reading →

Sunday 22 January 2023

JWT authentication in ASP.NET Core WebAPI

 Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI

Introduction
This article is meant to make the process of authentication and authorization easier using JSON Web Tokens and also to check the entire process with Swagger UI rather than PostMan.

What is a JSON Web Token?
A JSON Web Token (or JWT) is simply a JSON payload containing a particular claim. The key property of JWTs is that in order to confirm if they are valid we only need to look at the token itself. … A JWT is made of 3 parts: the Header, the Payload, and the Signature.

URL: https://jwt.io/

What is Swagger and how it is useful in ASP.NET Core Web API?
Swagger allows you to describe the structure of your APIs so that machines can read them.

Swashbuckle is an open-source project for generating Swagger documents for Web APIs that are built with ASP.NET Core MVC.

First, Create a New Project and select ASP.NET Core Web Application. 

Create an Authenticate Controller

Create below method under the Authenticate Controller:

private string GenerateJSONWebToken(LoginModel userInfo)
{
  var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
  var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

  var token = new JwtSecurityToken(_config["Jwt:Issuer"],
                _config["Jwt:Issuer"],
                null,expires: DateTime.Now.AddMinutes(120),
                signingCredentials: credentials);

 return new JwtSecurityTokenHandler().WriteToken(token);
}

Create another method for Login Validation to authenticate the user via the Hardcoded method:

  private async Task<LoginModel> AuthenticateUser(LoginModel login)
  {
      LoginModel user = null;

      //Validate the User Credentials      
      //Demo Purpose, I have Passed HardCoded User Information      
      if (login.UserName == "test")
      {
          user = new LoginModel { UserName = "test", Password = "123456" };
      }
      return user;
  }

Now create the Login Method to pass the parameters as JSON Format to Validate the User and to generate the Token (JWT).

  [AllowAnonymous]
  [HttpPost(nameof(Login))]
  public async Task<IActionResult> Login([FromBody] LoginModel data)
  {
      IActionResult response = Unauthorized();
      var user = await AuthenticateUser(data);
      if (data != null)
      {
          var tokenString = GenerateJSONWebToken(user);
          response = Ok(new { Token = tokenString, Message = "Success" });
      }
      return response;
  }

To use the JWT Token and Swagger, we need to install the below two into our project.


Add below functions in Authenticate controller class.
  [HttpGet(nameof(Get))]
  public async Task<IEnumerable<string>> Get()
  {
      var accessToken = await HttpContext.GetTokenAsync("access_token");
      return new string[] { accessToken };
  }

  [HttpGet(nameof(GetName))]
  public async Task<string> GetName()
  {
      return "Suraj Kumar Maddheshiya";
  }

  [HttpGet(nameof(GetAddress))]
  [AllowAnonymous]
  public async Task<string> GetAddress()
  {
      return "Delhi";
  }


Add this model class in project, as these are the required parameters to validate the User
  public class LoginModel
  {
      [Required]
      public string UserName { get; set; }
      [Required]
      public string Password { get; set; }
  }

Add this Property and Constructor to invoke the appsettings.json Secret JWT Key and its Issuer:

  private IConfiguration _config;
  public AuthenticateController(IConfiguration config)
  {
      _config = config;
  }

Add below code in appsettings.json. I have it added as basic key. You can also add it as per your wishes, and under Issuer, add your project URL.

  "Jwt": {
    "Key": "Thisismysecretkey",
    "Issuer": "http://localhost:28912"
  },

below method gets called by the runtime. Use this method in Startup.cs to add services to the container.

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllers();
    services.AddMvc();
    services.AddSwaggerGen(c =>
    {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "JWT Token Authentication API",
                    Description = "ASP.NET Core 3.1 Web API",
                    Version = "v1"
                });

                // To Enable authorization using Swagger (JWT)  
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Name = "Authorization",
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer",
                    BearerFormat = "JWT",
                    In = ParameterLocation.Header,
                    Description = "JWT Authorization header using the Bearer scheme.
                                 \r\n\r\n Enter 'Bearer' [space] and then your token
                    in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                          new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Type = ReferenceType.SecurityScheme,
                                    Id = "Bearer"
                                }
                            },
                            new string[] {}
                    }
                });
            });

    services.AddAuthentication(option =>
    {
  option.DefaultAuthenticateScheme =Microsoft.AspNetCore.Authentication.JwtBearer
                                            .JwtBearerDefaults.AuthenticationScheme;
       ption.DefaultChallengeScheme = Microsoft.AspNetCore.Authentication.JwtBearer
                                            .JwtBearerDefaults.AuthenticationScheme;
       option.DefaultScheme = Microsoft.AspNetCore.Authentication.JwtBearer
                                            .JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
       {
        options.TokenValidationParameters = new TokenValidationParameters
        {
                  ValidateIssuer = true,
                  ValidateAudience = true,
                  ValidateLifetime = false,
                  ValidateIssuerSigningKey = true,
                  ValidIssuer = Configuration["Jwt:Issuer"],
                  ValidAudience = Configuration["Jwt:Issuer"],
                  IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                      Configuration["Jwt:Key"])) //Configuration["JwtToken:SecretKey"]  
         };
       });
  }

Below 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",
                                                        "DotnetCoreWebAPI_Demo v1"));
         }

         //app.UseHttpsRedirection();
         app.UseRouting();
         app.UseAuthentication();
         app.UseAuthorization();
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllers();
         });

         // Swagger Configuration in API  
         app.UseSwagger();
         app.UseSwaggerUI(c =>
         {
             c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1");
         });
     }

When you run the application, you will get the swagger UI as shown below:


open Login url panel in above screenshot. Pass the parameters to generate the token and Then click on Execute Button -> Your token will be generated!


Click on the Authorize button and add this token under the Value box.
Add the token in the following manner as shown in the example below i.e Bearer token.
Click on the Authorize Button


Now every method in this document has been authorized!
If you found this article helps you, please give it a clap 👏

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

Continue Reading →

Saturday 21 January 2023

LINQ query related questions

 Find nth max salary using linq

I have a collection of Employee Data. 

//7000,6000,5500,5000
List<Employee> employees = new List<Employee>()
{
new Employee { Id = 1, UserName = "Anil" , Salary = 5000},
new Employee { Id = 2, UserName = "Sunil" , Salary = 6000},
new Employee { Id = 3, UserName = "Lokesh" , Salary = 5500},
new Employee { Id = 4, UserName = "Vinay" , Salary = 7000},
new Employee { Id = 5, UserName = "Vijay" , Salary = 7000},
new Employee { Id = 6, UserName = "vikas" , Salary = 6000}
};

See the below query example. I am finding 2nd highest max Salary.

Query Example 1:

  var result = employees.OrderByDescending(x => x.Salary)
  .Select(x => x.Salary).Distinct().Take(3)
  .Skip(3 - 1).FirstOrDefault();
Console.WriteLine(result);

Query Example 2:

var result = employees
      .GroupBy(e => e.Salary)
      .OrderByDescending(e=> e.Key)
      .Skip(1)
      .First();
Console.WriteLine(result.Key);

Query Example 3:

 //This will return all employees who has 2nd highest salary var result = employees .Where(x1 => x1.Salary == employees.OrderByDescending(x => x.Salary)
    .Select(x => x.Salary).Distinct().Take(2).Skip(2 - 1).FirstOrDefault()) .ToArray();
Console.WriteLine(result[0].Salary);




Continue Reading →

SQL Server Query related questions

1:- Finding nth highest salary in SQL?

Below is the Table structure:

Create table Employees
(
     ID int primary key identity,
     FirstName nvarchar(50),
     LastName nvarchar(50),
     Gender nvarchar(50),
     Salary int
)
GO

Insert into Employees values ('Suraj', 'Kumar', 'Male', 70000)
Insert into Employees values ('Rahul', 'Mad', 'Male', 60000)
Insert into Employees values ('Steve', 'jobs', 'Male', 46000)
Insert into Employees values ('Mahesh', 'kumar', 'Male', 70000)
Insert into Employees values ('Suresh', 'sinha', 'Male', 45000)
Insert into Employees values ('Ravi', 'kukreja', 'Female', 30000)
Insert into Employees values ('Priyanka', 'singh', 'Female', 36000)
Insert into Employees values ('Riya', 'Mishra', 'Male', 90000)
GO

Here we are finding 2nd highest Salary from Employee Table.

Using  Sub-Query with Max function

  Select Max(Salary) from Employee where Salary < (Select Max(Salary) from Employee)

Using  Sub-Query 

  SELECT TOP 1 SALARY
  FROM (
        SELECT DISTINCT TOP 2 SALARY
        FROM EMPLOYEE
        ORDER BY SALARY DESC
        ) RESULT
  ORDER BY SALARY ASC;

Using CTE

  WITH RESULT AS
  (
      SELECT DENSE_RANK() OVER (ORDER BY SALARY DESC) AS DENSERANK, SALARY
      FROM EMPLOYEES
  )
  SELECT TOP 1 SALARY
  FROM RESULT
  WHERE DENSERANK = 2

2:- Delete duplicate rows from table

WITH tblTemp as
(
   SELECT ROW_NUMBER() Over(PARTITION BY NameDepartment ORDER BY Name)
   AS RowNumber, * FROM emp
)
DELETE FROM tblTemp where RowNumber >1



Continue Reading →

Tuesday 17 January 2023

Understanding dependency injection Angular

 Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

Two main roles exist in the DI system: dependency consumer and dependency provider.

Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called Injector. When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as "root" injector) during the application bootstrap process, as well as any other injectors as needed. 

Providing dependency

Imagine there is a class called HeroService that needs to act as a dependency in a component.

The first step is to add the @Injectable decorator to show that the class can be injected.

@Injectable()
class HeroService {}

The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places:

At the Component level, using the providers field of the @Component decorator. In this case the HeroService becomes available to all instances of this component and other components and directives used in the template. For example:

  @Component({
    selector: 'hero-list',
    template: '...',
    providers: [HeroService]
  })
  class HeroListComponent {}

When you register a provider at the component level, you get a new instance of the service with each new instance of that component. 

At the NgModule level, using the providers field of the @NgModule decorator. In this scenario, the HeroService is available to all components, directives, and pipes declared in this NgModule. For example:

  @NgModule({
    declarations: [HeroListComponent]
    providers: [HeroService]
  })
  class HeroListModule {}

When you register a provider with a specific NgModule, the same instance of a service is available to all components in that NgModule. 

At the application root level, which allows injecting it into other classes in the application. This can be done by adding the providedIn: 'root' field to the @Injectable decorator:

  @Injectable({
    providedIn: 'root'
  })
  class HeroService {}

When you provide the service at the root level, Angular creates a single, shared instance of the HeroService and injects it into any class that asks for it. 

Injecting a dependency

The most common way to inject a dependency is to declare it in a class constructor. When Angular creates a new instance of a component, directive, or pipe class, it determines which services or other dependencies that class needs by looking at the constructor parameter types. For example, if the HeroListComponent needs the HeroService, the constructor can look like this:

  @Component({ … })
  class HeroListComponent {
    constructor(private service: HeroService) {}
  }

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector creates one using the registered provider, and adds it to the injector before returning the service to Angular.

When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.


Angular Providers: UseClass, UseValue, UseFactory & UseExisting 

Reference: https://angular.io/

Continue Reading →

Topics

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

Dotnet Guru Archives