angularspringauthenticationrequestjwt

authentication json web token springboot angular


i'm working on authentication with jwt and roles and i had an error: enter image description here

this is my code for the agent service in angular:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AgentAuthenService } from './agent-authen.service';
import { tap } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AgentService {
 private readonly path="http://localhost:9090";

  constructor(private httpclient: HttpClient, private agentAuthenServ:AgentAuthenService) { }

public login(mat: string, password: string){
  const url = `${this.path}/authentication`;
  const headers ={'Content-Type': 'application/json'};
  const body ={mat,password};
  return this.httpclient.post<any>(url,body,{headers}).pipe(tap(response =>{
    const token = response.token;
    const roles = response.agent.role;

    this.agentAuthenServ.setToken(token);
    this.agentAuthenServ.setToken(roles);
    
  }));
}

}

this is tha agent authentication service:


import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AgentAuthenService {

  constructor() { }

  public setToken(token:string){
    localStorage.setItem("token",token);
  }

  public getToken():string{
    return localStorage.getItem("token");
  }

  public setRole(role:[]){
    localStorage.setItem("role", JSON.stringify(role));
  }

  public getRole(): string[] {
    return JSON.parse(localStorage.getItem("role"));
  }

  public clearStorge(){
    localStorage.clear();
  }
  
  public logged(){
    return this.getRole() && this.getToken();
  }
}

and it says the problem in the login typeScript the line i commented :

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from '@angular/router';
import { AgentService } from '../_services/agent.service';
import { AgentAuthenService } from '../_services/agent-authen.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  constructor(private agentSer: AgentService, private agentAuthenSer: AgentAuthenService, private router: Router){}
  
  ngOnInit():void{}
  connect(loginF:NgForm){
    const agentPassword=loginF.value.agentPassword;
    const agentMat= loginF.value.agentMat
    //this.agentSer.login(agentPassword,agentMat).subscribe(
  (response:any) =>{

   const role = response.agent.role[0];
   this.agentAuthenSer.setRole(response.agent.role);
   this.agentAuthenSer.setToken(response.jwtToken);
   console.log(response);


   if(role=== 'ChargeClient'){
        this.router.navigate(['accueil/charge']);
   }else{ 
      if(role=== 'AnalysteCredit'){
        this.router.navigate(['accueil/analyste']);}
        else{

        if (role=== 'ChefAgence'){
          this.router.navigate(['accueil/chefA']);
        }else{
          this.router.navigate(['accueil/chefZ']);
        }}}} 
    );
   }
  } 

this is th web security (server side):

package com.example.banque.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSec extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntry jwtAuthenticationEntry;

        @Autowired
        private JwtRequestFilter jwtRequestFilter;


        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception{
            return super.authenticationManagerBean();

        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception{
            httpSecurity.cors();
            httpSecurity.csrf().disable().authorizeHttpRequests()
                    .antMatchers("/authentication").permitAll()
                    .antMatchers(HttpHeaders.ALLOW).permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntry)
                    .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        }


    }

this is json web token request filter:

package com.example.banque.configuration;

import com.example.banque.service.JwtService;
import com.example.banque.utils.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private JwtService jwtService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        final String header =request.getHeader("Authorization");
        String jwtToken=null;
        String agentMat=null;

        if (header != null && header.startsWith("Bearer ")){
           jwtToken= header.substring(7);

           try{
                agentMat=jwtUtil.getAgentMat(jwtToken);

           }catch(IllegalArgumentException e) {
               System.out.println("Ne peut pas récupérer le token");
           }catch (ExpiredJwtException e){
               System.out.println("Le token a expiré");
           }
        }else{
            System.out.println("Le token ne commence pas avec Bearer");
        }

        if (agentMat != null && SecurityContextHolder.getContext().getAuthentication() == null){
            UserDetails userDetails= jwtService.loadUserByUsername(agentMat);

            if (jwtUtil.validateToken(jwtToken, userDetails)){
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }

        filterChain.doFilter(request,response);
    }
}

and this is jwt controller:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin
public class JwtController {

    @Autowired
    private JwtService jwtService;

    @PostMapping({"/authentication"})
    public JwtResponse createJwtToken(@RequestBody JwtRequest jwtRequest) throws Exception{
       return jwtService.createJwtToken(jwtRequest);

    }

i know it's a lot but i really couldn't solve it especially this is my first time using roles and jwt but i really need to sove it


Solution

  • this what I did in my login, take a look and see if it can help you:

    //service
    public loginService(loginData:any){
      
        return this.http.post(`${this.apiServerUrl}/auth/login`,loginData)}
    
    //calling service
    this._auth.loginService(loginData).subscribe((val:any)=>{
       
       localStorage.setItem('token',val.jwt);
       
      })
    
    //and the the backend is almost the same
    

    I think you need to remove the pipe, and remove the {header}, and use INTERCEPTOR angular it's easy.

    the Role of INTERCEPTOR=> to set the header (for login you don't need a header because is permetALL) but you need INTERCEPTOR for other request getSommthing from backend you can watch this vedio in youtube to help you use interceptor https://www.youtube.com/watch?v=qugH2AbakEE&list=PLc2Ziv7051bZhBeJlJaqq5lrQuVmBJL6A&index=10