Skip to main content
The Intent.AspNetCore.Identity module introduces ASP.NET Core Identity for user authentication, authorization, and account management using Entity Framework Core. It provides a complete user management system with role-based access control.

Overview

ASP.NET Core Identity is a membership system that adds login functionality to your application. This module integrates Identity with your Intent Architect application, generating all the necessary entities, configurations, and infrastructure code.

What Gets Generated

Identity Entities

The module creates Identity user and role entities in your domain model:
public class ApplicationUser : IdentityUser<Guid>
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime? LastModifiedDate { get; set; }
}

public class ApplicationRole : IdentityRole<Guid>
{
    public ApplicationRole() { }
    
    public ApplicationRole(string roleName) : base(roleName) { }
}

AspNetCoreIdentityConfiguration

Configures Identity services in your application:
public static class AspNetCoreIdentityConfiguration
{
    public static IServiceCollection AddIdentityConfiguration(
        this IServiceCollection services)
    {
        services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequireLowercase = true;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequiredLength = 8;
            options.Password.RequiredUniqueChars = 1;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
            options.Lockout.MaxFailedAccessAttempts = 5;
            options.Lockout.AllowedForNewUsers = true;

            // User settings
            options.User.AllowedUserNameCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
            options.User.RequireUniqueEmail = true;

            // Sign in settings
            options.SignIn.RequireConfirmedEmail = false;
            options.SignIn.RequireConfirmedPhoneNumber = false;
        })
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

        return services;
    }
}

IdentityServiceCollectionExtensions

Extension methods for service registration:
public static class IdentityServiceCollectionExtensions
{
    public static IServiceCollection AddIdentityServices(
        this IServiceCollection services)
    {
        services.AddScoped<ICurrentUserService, CurrentUserService>();
        services.AddScoped<UserManager<ApplicationUser>>();
        services.AddScoped<SignInManager<ApplicationUser>>();
        services.AddScoped<RoleManager<ApplicationRole>>();

        return services;
    }
}

Key Features

User Management

Complete user registration and account management

Role-Based Access

Assign users to roles for authorization

Password Security

Configurable password complexity and hashing

Account Lockout

Automatic lockout after failed login attempts

Database Schema

Identity creates the following tables:
AspNetUsers
├── Id (uniqueidentifier)
├── UserName (nvarchar)
├── NormalizedUserName (nvarchar)
├── Email (nvarchar)
├── NormalizedEmail (nvarchar)
├── EmailConfirmed (bit)
├── PasswordHash (nvarchar)
├── SecurityStamp (nvarchar)
├── ConcurrencyStamp (nvarchar)
├── PhoneNumber (nvarchar)
├── PhoneNumberConfirmed (bit)
├── TwoFactorEnabled (bit)
├── LockoutEnd (datetimeoffset)
├── LockoutEnabled (bit)
└── AccessFailedCount (int)

AspNetRoles
├── Id (uniqueidentifier)
├── Name (nvarchar)
├── NormalizedName (nvarchar)
└── ConcurrencyStamp (nvarchar)

AspNetUserRoles
├── UserId (uniqueidentifier)
└── RoleId (uniqueidentifier)

AspNetUserClaims
AspNetRoleClaims
AspNetUserLogins
AspNetUserTokens

User Registration

Example user registration flow:
public class AccountService : IAccountService
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IApplicationDbContext _dbContext;

    public AccountService(
        UserManager<ApplicationUser> userManager,
        IApplicationDbContext dbContext)
    {
        _userManager = userManager;
        _dbContext = dbContext;
    }

    public async Task<IdentityResult> RegisterAsync(
        RegisterDto dto,
        CancellationToken cancellationToken)
    {
        var user = new ApplicationUser
        {
            UserName = dto.Email,
            Email = dto.Email,
            FirstName = dto.FirstName,
            LastName = dto.LastName,
            CreatedDate = DateTime.UtcNow
        };

        var result = await _userManager.CreateAsync(user, dto.Password);

        if (result.Succeeded)
        {
            // Assign default role
            await _userManager.AddToRoleAsync(user, "User");

            // Generate email confirmation token
            var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            // Send confirmation email...
        }

        return result;
    }
}

User Authentication

Example login flow:
public async Task<SignInResult> LoginAsync(
    LoginDto dto,
    CancellationToken cancellationToken)
{
    var user = await _userManager.FindByEmailAsync(dto.Email);
    if (user == null)
        return SignInResult.Failed;

    var result = await _signInManager.CheckPasswordSignInAsync(
        user,
        dto.Password,
        lockoutOnFailure: true);

    return result;
}

Role Management

Create and assign roles:
public class RoleService : IRoleService
{
    private readonly RoleManager<ApplicationRole> _roleManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public async Task CreateRoleAsync(string roleName)
    {
        if (!await _roleManager.RoleExistsAsync(roleName))
        {
            var role = new ApplicationRole(roleName);
            await _roleManager.CreateAsync(role);
        }
    }

    public async Task AssignRoleAsync(Guid userId, string roleName)
    {
        var user = await _userManager.FindByIdAsync(userId.ToString());
        if (user != null)
        {
            await _userManager.AddToRoleAsync(user, roleName);
        }
    }

    public async Task<List<string>> GetUserRolesAsync(Guid userId)
    {
        var user = await _userManager.FindByIdAsync(userId.ToString());
        if (user == null)
            return new List<string>();

        var roles = await _userManager.GetRolesAsync(user);
        return roles.ToList();
    }
}

Authorization

Use role-based authorization in controllers:
[Authorize]
[ApiController]
[Route("api/admin")]
public class AdminController : ControllerBase
{
    [Authorize(Roles = "Admin")]
    [HttpGet("users")]
    public async Task<ActionResult<List<UserDto>>> GetAllUsers()
    {
        // Only users in Admin role can access
    }

    [Authorize(Roles = "Admin,Manager")]
    [HttpGet("reports")]
    public async Task<ActionResult<ReportDto>> GetReports()
    {
        // Users in Admin OR Manager role can access
    }

    [Authorize(Policy = "RequireAdminAndManagerRoles")]
    [HttpPost("sensitive-action")]
    public async Task<ActionResult> SensitiveAction()
    {
        // Custom policy-based authorization
    }
}

Current User Service

Access the current authenticated user:
public interface ICurrentUserService
{
    Guid? UserId { get; }
    string? UserName { get; }
    bool IsAuthenticated { get; }
}

public class CurrentUserService : ICurrentUserService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CurrentUserService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public Guid? UserId
    {
        get
        {
            var userIdClaim = _httpContextAccessor.HttpContext?.User
                .FindFirstValue(ClaimTypes.NameIdentifier);
            
            return Guid.TryParse(userIdClaim, out var userId) 
                ? userId 
                : null;
        }
    }

    public string? UserName => 
        _httpContextAccessor.HttpContext?.User?.Identity?.Name;

    public bool IsAuthenticated => 
        _httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false;
}
Use in your application:
public class OrderService : IOrderService
{
    private readonly ICurrentUserService _currentUserService;
    private readonly IApplicationDbContext _dbContext;

    public async Task<Guid> CreateOrderAsync(
        CreateOrderDto dto,
        CancellationToken cancellationToken)
    {
        var order = new Order
        {
            CustomerId = _currentUserService.UserId.Value,
            CreatedBy = _currentUserService.UserName,
            // ... other properties
        };

        _dbContext.Orders.Add(order);
        await _dbContext.SaveChangesAsync(cancellationToken);

        return order.Id;
    }
}

Password Reset

Implement password reset flow:
public async Task<string> GeneratePasswordResetTokenAsync(string email)
{
    var user = await _userManager.FindByEmailAsync(email);
    if (user == null)
        throw new NotFoundException("User not found");

    return await _userManager.GeneratePasswordResetTokenAsync(user);
}

public async Task<IdentityResult> ResetPasswordAsync(
    string email,
    string token,
    string newPassword)
{
    var user = await _userManager.FindByEmailAsync(email);
    if (user == null)
        throw new NotFoundException("User not found");

    return await _userManager.ResetPasswordAsync(user, token, newPassword);
}

Email Confirmation

Implement email confirmation:
public async Task<string> GenerateEmailConfirmationTokenAsync(Guid userId)
{
    var user = await _userManager.FindByIdAsync(userId.ToString());
    if (user == null)
        throw new NotFoundException("User not found");

    return await _userManager.GenerateEmailConfirmationTokenAsync(user);
}

public async Task<IdentityResult> ConfirmEmailAsync(
    Guid userId,
    string token)
{
    var user = await _userManager.FindByIdAsync(userId.ToString());
    if (user == null)
        throw new NotFoundException("User not found");

    return await _userManager.ConfirmEmailAsync(user, token);
}

Two-Factor Authentication

Enable two-factor authentication:
public async Task<IdentityResult> EnableTwoFactorAsync(Guid userId)
{
    var user = await _userManager.FindByIdAsync(userId.ToString());
    if (user == null)
        throw new NotFoundException("User not found");

    await _userManager.SetTwoFactorEnabledAsync(user, true);
    return IdentityResult.Success;
}

public async Task<string> GenerateTwoFactorTokenAsync(Guid userId)
{
    var user = await _userManager.FindByIdAsync(userId.ToString());
    if (user == null)
        throw new NotFoundException("User not found");

    return await _userManager.GenerateTwoFactorTokenAsync(
        user,
        TokenOptions.DefaultPhoneProvider);
}

Installation

Intent.AspNetCore.Identity

Dependencies

  • Intent.Entities (>= 5.1.13)
  • Intent.EntityFrameworkCore (>= 5.0.26)
  • Intent.Modelers.Domain
  • Intent.OutputManager.RoslynWeaver

Integration

Identity integrates with:
  • Intent.Security.JWT - For JWT token-based authentication
  • Intent.AspNetCore.Identity.AccountController - For account management endpoints

Next Steps

JWT Authentication

Add JWT token authentication to Identity

Security.JWT

Configure JWT bearer authentication

Account Controller

Generate account management endpoints

Authorization

Implement role and policy-based authorization

Build docs developers (and LLMs) love