Skip to content

Getting Started with GrydAuth

This guide will walk you through setting up GrydAuth in your .NET application from scratch.

Prerequisites

  • .NET 9.0 SDK or later
  • PostgreSQL, SQL Server, or any EF Core compatible database
  • Basic understanding of ASP.NET Core authentication

Step 1: Create a New Project

bash
# Create new Web API project
dotnet new webapi -n MyApp.API -o src/MyApp.API

# Create class libraries for Clean Architecture
dotnet new classlib -n MyApp.Domain -o src/MyApp.Domain
dotnet new classlib -n MyApp.Application -o src/MyApp.Application
dotnet new classlib -n MyApp.Infrastructure -o src/MyApp.Infrastructure

# Add to solution
dotnet new sln -n MyApp
dotnet sln add src/MyApp.API
dotnet sln add src/MyApp.Domain
dotnet sln add src/MyApp.Application
dotnet sln add src/MyApp.Infrastructure

Step 2: Install GrydAuth Packages

bash
# Core packages
cd src/MyApp.Domain
dotnet add package GrydAuth.Domain

cd ../MyApp.Application
dotnet add package GrydAuth.Application

cd ../MyApp.Infrastructure
dotnet add package GrydAuth.Infrastructure

cd ../MyApp.API
dotnet add package GrydAuth.API
dotnet add package GrydAuth.Infrastructure

Step 3: Configure Database Context

Create your DbContext that extends GrydAuthDbContext:

csharp
// src/MyApp.Infrastructure/Data/AppDbContext.cs
using GrydAuth.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace MyApp.Infrastructure.Data;

public class AppDbContext : GrydAuthDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    // Add your custom DbSets here
    // public DbSet<Product> Products => Set<Product>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        
        // Your custom entity configurations
        // modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
    }
}

Step 4: Configure Program.cs

csharp
// src/MyApp.API/Program.cs
using GrydAuth.API.Controllers;
using GrydAuth.Infrastructure;
using Gryd.API.Extensions;
using MyApp.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// 1. Add GrydAuth services (Application + Infrastructure + JWT + Authorization)
// All configuration is read from appsettings.json sections
builder.Services.AddGrydAuth(builder.Configuration);

// 2. Add Controllers (includes GrydAuth API controllers)
builder.Services.AddControllers()
    .AddApplicationPart(typeof(AuthController).Assembly);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 3. Configure Database
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

// 4. Add Exception Handlers (IExceptionHandler pipeline - .NET 8+)
// IMPORTANT: Register in order of specificity (most specific first)
builder.Services.AddGrydAuthExceptionHandler();  // GrydAuth-specific (Redis, DB, etc.)
builder.Services.AddCoreExceptionHandler();       // Core fallback (validation, security, etc.)

var app = builder.Build();

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

// CRITICAL: Exception handling MUST be first to catch all exceptions
app.UseExceptionHandler();

app.UseHttpsRedirection();
app.UseRouting();

// Authentication (standard ASP.NET Core)
app.UseAuthentication();

// GrydAuth middleware (token blacklist, SmartFederation, AppId validation)
// CRITICAL: Must be AFTER Authentication but BEFORE Authorization
app.UseGrydAuth();

// Authorization (standard ASP.NET Core)
app.UseAuthorization();

app.MapControllers();

app.Run();

Step 5: Configure appsettings.json

json
{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=myapp;Username=postgres;Password=your_password"
  },
  "JwtSettings": {
    "SecretKey": "your-super-secret-key-at-least-256-bits-long-for-security",
    "Issuer": "myapp",
    "Audience": "myapp-users",
    "ExpirationMinutes": 60,
    "RefreshTokenExpirationDays": 7,
    "AppId": "my-app-id"
  },
  "GrydAuth": {
    "Cache": {
      "IsEnabled": true,
      "Redis": {
        "ConnectionString": "localhost:6379"
      }
    },
    "RequireConfirmedEmail": false,
    "AllowMultipleSessions": true
  },
  "MultiTenancy": {
    "IsEnabled": true
  },
  "PasswordPolicy": {
    "RequireDigit": true,
    "RequireLowercase": true,
    "RequireUppercase": true,
    "RequireNonAlphanumeric": true,
    "RequiredLength": 8
  },
  "Security": {
    "LockoutEnabled": true,
    "MaxFailedAccessAttempts": 5,
    "LockoutDurationMinutes": 15
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Configuration Sections

GrydAuth reads configuration from these sections:

  • JwtSettings - JWT token configuration (SecretKey, Issuer, Audience, etc.)
  • GrydAuth:Cache - Redis cache configuration for token blacklisting
  • MultiTenancy - Multi-tenant mode settings
  • PasswordPolicy - Password complexity requirements
  • Security - Account lockout and security settings

Step 6: Run Migrations

bash
# Create initial migration
cd src/MyApp.Infrastructure
dotnet ef migrations add InitialCreate --startup-project ../MyApp.API

# Apply migration
dotnet ef database update --startup-project ../MyApp.API

Step 7: Create Your First User

GrydAuth provides built-in endpoints for user management. Once your application is running:

Register a User

bash
POST /api/auth/register
Content-Type: application/json

{
  "email": "admin@example.com",
  "password": "Admin@123!",
  "fullName": "System Administrator"
}

Login

bash
POST /api/auth/login
Content-Type: application/json
X-App-Id: my-app-id

{
  "email": "admin@example.com",
  "password": "Admin@123!",
  "isPasswordEncrypted": false
}

Response:

json
{
  "isSuccess": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
    "expiresAt": "2026-01-29T13:00:00Z",
    "permissions": ["read:users", "update:users"],
    "isFirstLogin": false,
    "mustChangePassword": false,
    "isGlobal": false,
    "requiresTenantSelection": false,
    "tokenType": "Tenant",
    "currentTenant": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Default Tenant",
      "isDefault": true
    }
  }
}

Multi-Tenant Authentication

When multi-tenancy is enabled and the user has access to multiple tenants:

  1. First login returns a Global Token (2min TTL, isGlobal: true)
  2. Use POST /api/auth/switch-tenant with the target tenant ID
  3. You'll receive a Tenant Token (60min TTL) with full access

Use the Token

bash
GET /api/auth/me
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response (basic info from JWT):

json
{
  "isSuccess": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "System Administrator",
    "email": "admin@example.com",
    "roles": ["Admin"],
    "permissions": ["read:users", "update:users"]
  }
}

Complete profile (with include=profile):

bash
GET /api/auth/me?include=profile
# or
GET /api/auth/me/complete

Step 8: Protect Your Endpoints

Using Built-in Attributes

csharp
using GrydAuth.API.Attributes;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
[Authorize] // Requires authentication
public class ProductsController : ControllerBase
{
    // Anyone authenticated can read
    [HttpGet]
    [RequirePermission("read:products")]
    public IActionResult GetAll() => Ok(new[] { "Product 1", "Product 2" });
    
    // Only users with create permission
    [HttpPost]
    [RequirePermission("create:products")]
    public IActionResult Create([FromBody] CreateProductRequest request) 
        => Created("", new { Id = Guid.NewGuid() });
    
    // Only admins
    [HttpDelete("{id}")]
    [Authorize(Roles = "Admin")]
    public IActionResult Delete(Guid id) => NoContent();
}

Using Policy-Based Authorization

csharp
// Program.cs
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("CanManageUsers", policy =>
        policy.RequirePermission("create:users", "update:users", "delete:users"));
    
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireRole("Admin", "SuperAdmin"));
});

// Controller
[HttpPost]
[Authorize(Policy = "CanManageUsers")]
public IActionResult CreateUser([FromBody] CreateUserRequest request) { ... }

Next Steps

Now that you have GrydAuth set up, explore these topics:

Common Issues

Token Validation Fails

Ensure your SecretKey is at least 256 bits (32 characters) and consistent across all environments.

CORS Issues

Add CORS configuration before authentication middleware:

csharp
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.WithOrigins("http://localhost:3000")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

// In pipeline (before UseAuthentication)
app.UseCors();

Database Connection

Ensure your connection string is correct and the database exists. PostgreSQL example:

bash
# Create database
psql -U postgres -c "CREATE DATABASE myapp;"

Released under the MIT License.