Authentication and Authorization in Angular and C#

Introduction

Implementing authentication and authorization in an Angular application with a backend in C# involves several steps. I'll provide you with a step-by-step guide, assuming you are using ASP.NET Core for the C# backend. The example includes Token-based authentication using JSON Web Tokens (JWT) and role-based authorization.

Backend (ASP.NET Core C#)

Create a new ASP.NET Core Web API Project.

Use Visual Studio or the command line to create a new ASP.NET Core Web API project.

dotnet new webapi -n myapi

Install Necessary NuGet Packages

Install the required packages for handling authentication and JWT.

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

Configure Authentication and JWT in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // Other configurations...

    // Configure JWT authentication
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey")),
            ValidIssuer = "YourIssuer",
            ValidAudience = "YourAudience"
        };
    });

    // Other services...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Other configurations...

    app.UseAuthentication();

    // Other middleware...
}

Create an Authentication Controller

Create a controller to handle user authentication.

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
    // Implement registration, login, and other authentication methods
}

Generate JWT Tokens on Login

In your authentication controller, generate JWT tokens on successful login.

// Example login method
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel model)
{
    // Validate credentials and generate JWT
    var token = GenerateJwtToken(model.Username);
    return Ok(new { Token = token });
}

private string GenerateJwtToken(string username)
{
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, username),
        // Add other claims as needed
    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"));
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: "YourIssuer",
        audience: "YourAudience",
        claims: claims,
        expires: DateTime.Now.AddMinutes(30),
        signingCredentials: creds
    );

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

Implement Authorization with Roles

In your controllers, use the Authorize attribute with roles to restrict access.

[Authorize(Roles = "Admin")]
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
    // Actions accessible only to users with the "Admin" role
}

Frontend (Angular)

Create an Angular Project.

Use the Angular CLI to create a new Angular project.

ng new myApp

Install Angular Packages

Install packages for authentication.

npm install @auth0/angular-jwt

Implement Authentication Service

Create an authentication service to handle login and store tokens.

// authentication.service.ts
import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private jwtHelper = new JwtHelperService();

  login(token: string): void {
    localStorage.setItem('token', token);
  }

  logout(): void {
    localStorage.removeItem('token');
  }

  isLoggedIn(): boolean {
    const token = localStorage.getItem('token');
    return !this.jwtHelper.isTokenExpired(token);
  }
}

Implement Login Component

Create a component for user login.

// login.component.ts
import { Component } from '@angular/core';
import { AuthService } from './auth.service';

@Component({
  selector: 'app-login',
  template: `
    <button (click)="login()">Login</button>
  `
})
export class LoginComponent {
  constructor(private authService: AuthService) {}

  login(): void {
    // Call your authentication service to perform login
    // and store the token in AuthService
    const token = 'your_generated_token';
    this.authService.login(token);
  }
}

Secure Components with AuthGuard

Create an AuthGuard to secure routes based on authentication status.

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

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.authService.isLoggedIn()) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }
}

Use AuthGuard in Routes

Apply the AuthGuard to routes to control access.

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth.guard';
import { AdminComponent } from './admin/admin.component';

const routes: Routes = [
  { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
  // Other routes...
];

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

Conclusion

This is a basic example, and you may need to adapt it based on your specific requirements. Ensure to handle security on the server-side and validate tokens properly. Additionally, use HTTPS for production to secure communication between the Angular app and the ASP.NET Core backend.