Skip to main content

Authentication

Authentication implementation using Microsoft Identity Framework (ASP.NET Core Identity).


Authentication Endpoints

User Login

Endpoint: POST /login

Request Body:

{
"email": "user@example.com",
"password": "SecurePassword123!",
"useCookies": true,
"useSessionCookies": false
}

Response: 200 OK

{
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600,
"refreshToken": "refresh-token-here",
"user": {
"id": "uuid-here",
"email": "user@example.com",
"name": "John Doe",
"roles": ["client"]
}
}

Roles:

  • client - Regular user with access to create requests and view their own data
  • admin - Administrator with access to backoffice, user management, and all client data

User Registration (Deprecated)

Endpoint: POST /register

Deprecated

This endpoint is deprecated and will return 404 Not Found. Use the Client Registration endpoints instead.

Response: 404 Not Found

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not Found",
"status": 404,
"detail": "Endpoint not found. Please use POST /client/register for client registration."
}

Client Registration

Dedicated Page

For complete client registration documentation, including the registration endpoint, email confirmation flow, password requirements, and registration process, see Client Registration.

Quick Reference:

  • Registration Endpoint: POST /client/register
  • Email Confirmation: GET /confirmEmail
  • Resend Confirmation: POST /resendConfirmationEmail

Related Pages:


Refresh Token

Endpoint: POST /refresh

Request Body:

{
"refreshToken": "refresh-token-here"
}

Response: 200 OK

{
"tokenType": "Bearer",
"accessToken": "new-access-token",
"expiresIn": 3600,
"refreshToken": "new-refresh-token"
}

Forgot Password

Endpoint: POST /forgotPassword

Request Body:

{
"email": "user@example.com"
}

Response: 200 OK

{
"message": "Password reset email sent"
}

Reset Password

Endpoint: POST /resetPassword

Request Body:

{
"email": "user@example.com",
"resetCode": "reset-code-from-email",
"newPassword": "NewSecurePassword123!"
}

Response: 200 OK

{
"message": "Password reset successfully"
}

User Logout

Endpoint: POST /logout

Headers:

Authorization: Bearer {access-token}

Request Body: Empty or

{}

Response: 200 OK

{
"message": "Logged out successfully"
}

Error Responses

All endpoints may return the following error responses:

400 Bad Request

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"Email": ["The Email field is required."],
"Password": ["The Password field is required."]
}
}

401 Unauthorized

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid email or password."
}

404 Not Found

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not Found",
"status": 404,
"detail": "User not found."
}

Roles and Authorization

User Roles

The MicDots platform has two primary user roles:

Client Role (role: "client"):

  • Regular users who create text-to-audio requests
  • Can view and manage their own requests
  • Can view their own profile and statistics
  • Can update their own account information
  • Cannot access admin endpoints or other users' data

Admin Role (role: "admin"):

  • Platform administrators with elevated privileges
  • Can view and manage all client accounts
  • Can view and process all text-to-audio requests
  • Can access the admin backoffice dashboard
  • Can update request statuses and upload audio files
  • Full access to platform analytics and reports

Role-Based Access Control

How Roles Work:

  1. Role is assigned during user creation (registration or admin invitation)
  2. Role is included in the JWT access token claims
  3. Backend validates role on each API request
  4. Frontend shows/hides UI elements based on user role

JWT Token Claims:

{
"sub": "uuid-here",
"email": "user@example.com",
"name": "John Doe",
"roles": ["client"],
"exp": 1706025600,
"iss": "https://micdots.com",
"aud": "https://micdots.com"
}

Authorization Examples

Client Access:

// Client can only access their own data
GET /client/THEIR_OWN_ID // ✅ Allowed
GET /client/ANOTHER_USER_ID // ❌ 403 Forbidden

// Client can create requests
POST /api/v1/text-to-speech // ✅ Allowed

// Client can view own requests
GET /api/v1/text-to-speech // ✅ Allowed (filtered to own requests)
GET /api/v1/text-to-speech/:id // ✅ Allowed (if owns the request)

// Client cannot update others' requests
PUT /api/v1/text-to-speech/OTHER_USER_ID // ❌ 403 Forbidden

Admin Access:

// Admin can access any client data
GET /client/ANY_CLIENT_ID // ✅ Allowed
GET /client // ✅ Allowed (list all clients)

// Admin can access all requests
GET /api/v1/text-to-speech // ✅ Allowed (sees all requests)
GET /api/v1/text-to-speech/:id // ✅ Allowed (any request)

// Admin can update any request
PUT /api/v1/text-to-speech/:id // ✅ Allowed (update status, audioUrl, etc.)
POST /api/v1/text-to-speech/upload-url // ✅ Allowed (get pre-signed S3 URL)

Error Responses for Authorization

403 Forbidden (Insufficient Permissions):

{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "You do not have permission to access this resource.",
"detail": "This endpoint requires admin role."
}
}

Example Scenarios:

  • Client trying to access admin endpoints → 403 Forbidden
  • Client trying to view another client's data → 403 Forbidden
  • Unauthenticated user trying to access protected endpoint → 401 Unauthorized

Authentication Flow

Login Flow

Registration Flow

For the complete client registration and email confirmation flow, see Client Registration.


Token Management

Access Token

  • Type: JWT (JSON Web Token)
  • Expiration: 1 hour (3600 seconds)
  • Storage: Memory or secure HTTP-only cookie
  • Usage: Include in Authorization: Bearer {token} header for all protected endpoints

Refresh Token

  • Type: Opaque token
  • Expiration: 7 days (configurable)
  • Storage: Secure HTTP-only cookie (recommended) or secure storage
  • Usage: Use to obtain new access tokens via POST /refresh when access token expires

Security Best Practices

Password Requirements

  • Minimum 8 characters
  • At least one uppercase letter (A-Z)
  • At least one lowercase letter (a-z)
  • At least one digit (0-9)
  • At least one special character (!@#$%^&*)

Token Security

  • Store tokens securely (HTTP-only cookies recommended)
  • Never expose tokens in URLs or logs
  • Implement token rotation on refresh
  • Revoke refresh tokens on logout

Rate Limiting

  • Login attempts: 5 per 15 minutes per IP
  • Registration: 3 per hour per IP
  • Password reset: 3 per hour per email

HTTPS Only

  • All authentication endpoints must use HTTPS in production
  • Set Secure flag on cookies
  • Enable HSTS (HTTP Strict Transport Security)

Configuration

appsettings.json

{
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudiences": [
"http://localhost:5000",
"https://localhost:5001",
"https://micdots.com"
],
"ValidIssuer": "https://micdots.com"
}
}
},
"IdentityOptions": {
"Password": {
"RequireDigit": true,
"RequireLowercase": true,
"RequireUppercase": true,
"RequireNonAlphanumeric": true,
"RequiredLength": 8
},
"Lockout": {
"DefaultLockoutTimeSpan": "00:15:00",
"MaxFailedAccessAttempts": 5,
"AllowedForNewUsers": true
},
"User": {
"RequireUniqueEmail": true
},
"SignIn": {
"RequireConfirmedEmail": true
}
},
"JwtSettings": {
"SecretKey": "your-secret-key-here-min-32-chars",
"Issuer": "https://micdots.com",
"Audience": "https://micdots.com",
"ExpiryMinutes": 60
}
}

Database Schema

AspNetUsers Table

ColumnTypeConstraints
Idstring (GUID)Primary Key
UserNamestring(256)Unique, Not Null
NormalizedUserNamestring(256)Unique, Indexed
Emailstring(256)Unique, Not Null
NormalizedEmailstring(256)Unique, Indexed
EmailConfirmedbooleanNot Null, Default: false
PasswordHashstringNot Null
SecurityStampstringNot Null
ConcurrencyStampstringNot Null
PhoneNumberstringNullable
PhoneNumberConfirmedbooleanNot Null, Default: false
TwoFactorEnabledbooleanNot Null, Default: false
LockoutEndDateTimeOffsetNullable
LockoutEnabledbooleanNot Null, Default: true
AccessFailedCountintNot Null, Default: 0

Additional Identity Tables

  • AspNetRoles - User roles
  • AspNetUserRoles - User-role mapping
  • AspNetUserClaims - Custom user claims
  • AspNetUserLogins - External login providers
  • AspNetUserTokens - User tokens (refresh, reset, etc.)

Testing Endpoints

Using cURL

Login:

curl -X POST http://localhost:5000/login \
-H "Content-Type: application/json" \
-d '{
"email": "client@example.com",
"password": "Test123!@#",
"useCookies": false
}'

Access Protected Endpoint:

curl -X GET http://localhost:5000/manage/info \
-H "Authorization: Bearer {your-access-token}"