Angular 7 + Spring Boot Basic Authentication Example| JavaInUse



Angular 7 + Spring Boot Basic Authentication Example

In previous tutorial we had implemented - Angular 7 + Spring Boot Login Example. We had also created a menu with links to pages.
In previous example we had implemented hardcoded username and password using the angular code for login. In this tutorial we will be implementing Basic Authentication using Spring Boot. All the REST calls made from Angular to Spring Boot will be authenticated using Basic Authentication. Basic authentication is a simple authentication scheme built using the HTTP protocol. When using this protocol the HTTP requests have Authorization header which has the word Basic followed by a space and base 64 encoded string username:password.
basic authentication example
In a previous tutorial we had implemented Spring Boot + Basic Authentication Example.
Also in this tutorial the angular code though functional is not optimized. There is lot of repetition of the Basic Authentication code for adding header. We will be optimizing this code using the HTTPInterceptors in the next tutorial.
spring boot angular basic authentication example

Angular 7+ Spring Boot - Table of Contents

Angular 7 + Spring Boot Application Hello World Example Angular 7 + Spring Boot Application CRUD Example Angular 7 + Spring Boot Application Login Example Angular 7 + Spring Boot Application Basic Authentication Example Angular 7 + Spring Boot Basic Auth Using HTTPInterceptor Example Angular 7 + Spring Boot JWT Authentication Hello World Example

Video

This tutorial is explained in the below Youtube Video.

  • Basic Authentication using Spring Boot

    In previous tutorial we had implemented Spring Boot REST API's for performing CRUD operations. In this tutorial we will be adding the basic authentication to this application.
    We will be modifying the code we developed in the previous tutorial The maven project is as follows -
    spring boot angular basic authentication project
    The pom.xml is defined as follows -
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>com.javainuse</groupId>
    	<artifactId>angular-spring</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.1.1.RELEASE</version>
    		<relativePath /> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-security</artifactId>
    		</dependency>
    
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    
    </project>
    
    Next we configure Spring Security to make use of in memory authentication. Also here we allow OPTIONS call to be allowed. These OPTIONS call are made by Angular application to Spring Boot application. Also here we are disabling csrf. Previous Spring Boot Security - Enabling CSRF Protection Tutorial we had seen what is csrf.
    package com.javainuse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    	@Override
    	protected void configure(HttpSecurity http) throws Exception {
    		http.csrf().disable().
    
    				authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().anyRequest().authenticated()
    				.and().httpBasic();
    	}
    
    	@Autowired
    	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    		auth.inMemoryAuthentication().withUser("javainuse").password("{noop}password").roles("USER");
    	}
    }
    
    Define a model class user. This user object will be returned to Angular when its user tries to login using the username and password. Only if the basic auth credentials are correct will this object be returned by the controller.
    package com.javainuse.model;
    
    public class User {
    	private String status;
    
    	public User(String status) {
    		this.status = status;
    	}
    
    	public String getStatus() {
    		return status;
    	}
    
    	public void setStatus(String status) {
    		this.status = status;
    	}
    
    }
    
    In the controller we define another REST API for returning the user object.
    package com.javainuse.controller;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.javainuse.model.User;
    import com.javainuse.model.Employee;
    
    @CrossOrigin()
    @RestController
    @RequestMapping({ "/employees" })
    public class TestController {
    
    	private List<Employee> employees = createList();
    
    	@GetMapping(produces = "application/json")
    	public List<Employee> firstPage() {
    		return employees;
    	}
    
    
    	@GetMapping(produces = "application/json")
    	@RequestMapping({ "/validateLogin" })
    	public User validateLogin() {
    		return new User("User successfully authenticated");
    	}
    
    	@DeleteMapping(path = { "/{id}" })
    	public Employee delete(@PathVariable("id") int id) {
    		Employee deletedEmp = null;
    		for (Employee emp : employees) {
    			if (emp.getEmpId().equals(id)) {
    				employees.remove(emp);
    				deletedEmp = emp;
    				break;
    			}
    		}
    		return deletedEmp;
    	}
    
    	@PostMapping
    	public Employee create(@RequestBody Employee user) {
    		employees.add(user);
    		return user;
    	}
    
    	private static List<Employee> createList() {
    		List<Employee> tempEmployees = new ArrayList<>();
    		Employee emp1 = new Employee();
    		emp1.setName("emp1");
    		emp1.setDesignation("manager");
    		emp1.setEmpId("1");
    		emp1.setSalary(3000);
    
    		Employee emp2 = new Employee();
    		emp2.setName("emp2");
    		emp2.setDesignation("developer");
    		emp2.setEmpId("2");
    		emp2.setSalary(3000);
    		tempEmployees.add(emp1);
    		tempEmployees.add(emp2);
    		return tempEmployees;
    	}
    }
    
  • Implement changes for Basic Authentication on the Angular side

    We will be modifying the code we developed in the previous tutorial The angular project we will be developing is as follows-
    angular 7 login project
    In the http-client.service.ts we will be adding the basic auth header before making the REST calls.
    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    
    export class Employee{
      constructor(
        public empId:string,
        public name:string,
        public designation:string,
        public salary:string,
      ) {}
      
    }
    
    @Injectable({
      providedIn: 'root'
    })
    export class HttpClientService {
    
      constructor(
        private httpClient:HttpClient
      ) { 
         }
    
         getEmployees()
      {
        let username='javainuse'
        let password='password'
      
        const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
        return this.httpClient.get<Employee[]>('http://localhost:8080/employees',{headers});
      }
    
    
      public deleteEmployee(employee) {
        let username='javainuse'
        let password='password'
      
        const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
        return this.httpClient.delete<Employee>("http://localhost:8080/employees" + "/"+ employee.empId,{headers});
      }
    
      public createEmployee(employee) {
        let username='javainuse'
        let password='password'
      
        const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
        return this.httpClient.post<Employee>("http://localhost:8080/employees", employee,{headers});
      }
     
    }
    
    
    Previously the authentication.service.ts used to check the credentials against hardcoded values. Now we will make a REST call using Basic Auth header. Only if the User object is returned will be login be successful.
    import { Injectable } from '@angular/core';
    import { HttpClientService } from './http-client.service';
    import { HttpClient,HttpHeaders } from '@angular/common/http';
    import { map } from 'rxjs/operators';
    
    export class User{
      constructor(
        public status:string,
         ) {}
      
    }
    
    @Injectable({
      providedIn: 'root'
    })
    export class AuthenticationService {
      constructor(
        private httpClient:HttpClient
      ) { 
         }
    
      authenticate(username, password) {
        const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
        return this.httpClient.get<User>('http://localhost:8080/employees/validateLogin',{headers}).pipe(
         map(
           userData => {
            sessionStorage.setItem('username',username);
            return userData;
           }
         )
    
        );
      }
    
      isUserLoggedIn() {
        let user = sessionStorage.getItem('username')
        console.log(!(user === null))
        return !(user === null)
      }
    
      logOut() {
        sessionStorage.removeItem('username')
      }
    }
    
    
    In the login.service.ts we check if the valid user is returned by the authentication service. If yes then login is successful and the user is forwarded to the employee page.
    import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
    import { AuthenticationService } from '../service/authentication.service';
    
    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.css']
    })
    export class LoginComponent implements OnInit {
    
      username = ''
      password = ''
      invalidLogin = false
    
      constructor(private router: Router,
        private loginservice: AuthenticationService) { }
    
      ngOnInit() {
      }
    
      checkLogin() {
        (this.loginservice.authenticate(this.username, this.password).subscribe(
          data => {
            this.router.navigate([''])
            this.invalidLogin = false
          },
          error => {
            this.invalidLogin = true
    
          }
        )
        );
    
      }
    
    }
    
    Now if we go to localhost:4200/login. Login using the credentials -username ='javainuse' ,password='password'. User will be authenticated using Basic Authentication and forwarded to employees page.
    angular 7 login page

    angular 7 login success

Download Source Code

Download it -
GITHUB- Angular 7 Basic Authentication example code
Spring Boot Basic Authentication code