Learn Technologies

Angular 8 – ASP.Net Core Tutorial part 6 Bearer Authentication

In this part of tutorial, we will see together, how to make Bearer authentication.

What’s Bearer Authentication

Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The name “Bearer authentication” can be understood as “give access to the bearer of this token.” The bearer token is a cryptic string, usually generated by the server in response to a login request. The client must send this token in the Authorization header when making requests to protected resources.

The Bearer authentication scheme was originally created as part of OAuth 2.0 in RFC 6750, but is sometimes also used on its own. Similarly to Basic authentication, Bearer authentication should only be used over HTTPS (SSL).

Add Bearer Authentication in Web API

In the Manage NuGet packages, search the 2 packages Microsoft.AspNetCore.Authentication.JwtBearer and System.IdentityModel.Tokens.Jwt and install both of them on WebAPI project.

Bearer authentication

After that, add new property in UserModel class called Token type of string.

namespace Forms.Models
{
    public class UserModel: BaseModel
    {
        /// <summary>
        /// Gets or sets the FirstName.
        /// </summary>
        public string FristName { get; set; }

        /// <summary>
        /// Gets or sets the LastName.
        /// </summary>
        public string LastName { get; set; }

        /// <summary>
        /// Gets or sets the Email.
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// Gets or sets the mobile number.
        /// </summary>
        public string mobileNumber { get; set; }

        public string Token { get; set; }

    }
}

In the UsersController class, we need to generate a new token when user makes a successful login.
In fact, token represent an encrypted identity of the logged user. It can contains Role, groups in which user is subscribed, profile …
We define also in how much times, the token will be expired.

[AllowAnonymous]
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel loginModel)
{
            var user = usersManager.Login(loginModel);
            if(user == null)
            {
                return BadRequest(new { message = "Login or password is incorrect" });
            }

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(appSettings.SecretKey);
            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.Id.ToString())
                }),
                Expires = DateTime.UtcNow.AddDays(2),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            user.Token = tokenHandler.WriteToken(token);

            return Ok(user);
 }

And don’t forget to put [Authorize] attribute decoration for the controller. and [AllowAnonymous] for login action. That’s mean every one can call the login action.

Add new Folder called Tools in which, we add new class AppSettings contains one property SecretKey.

    public class AppSettings
    {
        public string SecretKey { get; set; }
    }

In the AppSettings.json, we add our secret key for encryption:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AppSettings": {
    "SecretKey": "kdhjzekdzokdhj jdoazipdjzeio oizedjoidfj ezoiezguoiersphrn,cjreaiop"
  }
}

Finally, let’s make configure the requests in order to make sure that all the request header contains a valid token.
Let’s move to Startup class and add the flowing code:

  public void ConfigureServices(IServiceCollection services)
  {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            var appSettingsSection = Configuration.GetSection("AppSettings");
            services.Configure<AppSettings>(appSettingsSection);

            // Configure jwt authentication.
            var appSettings = appSettingsSection.Get<AppSettings>();
            var secretKey = Encoding.ASCII.GetBytes(appSettings.SecretKey);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(x =>
           {
               x.RequireHttpsMetadata = false;
               x.SaveToken = true;
               x.TokenValidationParameters = new TokenValidationParameters
               {
                   ValidateIssuerSigningKey = true,
                   IssuerSigningKey = new SymmetricSecurityKey(secretKey),
                   ValidateIssuer = false,
                   ValidateAudience = false
               };
           });

            services.AddScoped<FormsContext>();
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddScoped<IUsersManager, UsersManager>();
            services.AddScoped<IUsersRepository, UsersRepository>();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {Title = "Forms Api", Version = "V1" });
            });
 }

Angular modifications

In angular project, add new property in user-model.ts

export class UserModel {
    id: number;
    firstName: string;
    lastName: string;
    email: string;
    password: string;
    mobileNumber: string;
    token?: string;
}

In user-service.ts, we need to expose logout method and make some modifications in login method:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { UserModel } from "../models/user-model";
import { LoginModel } from "../models/login-model";
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class UsersServiceService {

  private currentUserSubject: BehaviorSubject<UserModel>;
  currentUser: Observable<UserModel>;

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' })
  };

  private baseUrl = "/api/Users";
  constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<UserModel>(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
  }

  public get currentUserObject():UserModel{
    return this.currentUserSubject.value;
  }

  registerUser(userModel: UserModel) {
    return this.httpClient.post<UserModel>(this.baseUrl, userModel, this.httpOptions);
  }

  login(loginModel: LoginModel) {
    return this.httpClient.post<any>(`${this.baseUrl}/login`, loginModel, this.httpOptions)
    .pipe(map(user=>{
      localStorage.setItem('currentUser', JSON.stringify(user));
      this.currentUserSubject.next(user);
      return user
    }));
  }

  logout(){
    localStorage.removeItem('currentUser');
    this.currentUserSubject.next(null);
  }
}

Please, See the video for the rest of code.

Follow Me For Updates

Subscribe to my YouTube channel or follow me on Twitter or GitHub to be notified when I post new content.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x