Angular 17 app with .NET 8 Identity role based authentication

242 Views Asked by At

I am new to Angular and .NET. I am using an ASP.NET Core 8 Web API as my backend, and I am using JWT token. Now I want to protect my routes in my Angular 17 app to show routes based on the user role for example Admin view should be different than Employee view.

What is the best way to do that? Should I create a service to decrypt my token and return the role? Or there is a better option?

My backend program.cs:

using EmployeeManagement.Database;
using EmployeeManagement.Entities;
using EmployeeManagement.Shared.Common;
using EmployeeManagement.Shared.Configrations;
using EmployeeManagement.Shared.Services.Department;
using EmployeeManagement.Shared.Services.Employee;
using EmployeeManagement.Shared.Services.UserRole;
using EmployeeManagement.Shared.Services.VacationRequests;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Header,
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey
    });
    options.OperationFilter<SecurityRequirementsOperationFilter>();
});

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection") ?? 
    throw new InvalidOperationException( "Connection string Not found")));

builder.Services.AddAuthorization();

builder.Services.AddIdentityApiEndpoints<ApplicationUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
        .AddCertificate();
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
builder.Services.AddAutoMapper(
    typeof(EmployeeMapperConfig),
    typeof(UserRoleReMapperConfig),
    typeof(DepartmentMapperConfig),
    typeof(VacationRequestsMapperConfig),
    typeof(ApplicationUserMapperConfig)
 );
builder.Services.AddScoped<IEmployeeService, EmployeeService>();
builder.Services.AddScoped<IUserRole, UserRoleService>();
builder.Services.AddScoped<IDepartmentService, DepartmentServices>();
builder.Services.AddScoped<IVacationRequestsService, VacationRequestsService>();

builder.Services.AddFluentValidation();
builder.Services.AddValidatorsFromAssemblyContaining<IAssemblyMarker>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.MapIdentityApi<ApplicationUser>();

app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

My Angular app.routes.ts:

import { Routes } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { HomeComponent } from './pages/home/home.component';
import { UsersComponent } from './pages/users/users.component';
import { authGuardGuard } from './guard/auth-guard.guard';

export const routes: Routes = [
      {
        path: 'login',
        loadComponent:()=> import("./pages/login/login.component").then(e=>LoginComponent)
      },
      {
        path: '',
        loadComponent:()=> import("./pages/login/login.component").then(e=>LoginComponent)
      },
      {
        path: 'home',
        canMatch:[authGuardGuard],  
        loadComponent:()=> import("./pages/home/home.component").then(e=>HomeComponent)
      },
      {
        path:'',
        canMatch:[authGuardGuard],
        component: HomeComponent,
        children:[
          {
            path: 'users',
            loadComponent:()=> import("./pages/users/users.component").then(e=>UsersComponent)
          }
        ]
      }
];

My authInterceptorInterceptor:

import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptorInterceptor: HttpInterceptorFn = (req, next) => {
  const AccessToken = localStorage.getItem('AccessToken');
  const CloneRequest = req.clone({
    setHeaders:{
      Authorization: `Bearer ${AccessToken}`,
      'Content-Type': 'application/json' // Set content type here
    }
  })
  return next(CloneRequest);
};
0

There are 0 best solutions below