Authentication and User Management using AWS Cognito Authentication
Author(s)
- Reshmi Karan
Last Updated Date
2025-09-19
SRS References
Version History
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 2025-09-19 | Initial draft | Reshmi Karan |
Feature Overview
Objective:
Implement a comprehensive authentication system using AWS Cognito with custom UI, supporting multiple authentication providers (Google, Facebook, Azure AD), role-based access control (RBAC), multi-factor authentication (MFA), and multi-tenant architecture with dynamic scope injection using AWS Lambda and SSM Parameter Store.
Cognito user attributes
Use Cognito standard + custom attributes. Example custom attributes: custom:role — admin|agency|grouphead|dealer custom:consumerId — dealerId or agencyId custom:scopes — optional comma-separated list of additional scopes (tenant-specific overrides) email, sub, etc. (standard)
Scope:
- AWS Cognito User Pool with federated identity providers
- Custom UI for authentication flows
- .NET backend API for authentication logic
- AWS Lambda function for pre-token generation with dynamic scopes
- AWS SSM Parameter Store for configuration management
- Multi-tenant support with dealerId/agencyId tagging
- RBAC with four user roles: admin, agency, grouphead, dealer
Dependencies:
- AWS Cognito User Pool
- AWS Lambda Runtime
- AWS SSM Parameter Store
- .NET 8 SDK
- AWS SDK for .NET
Requirements
- Support federated login with Google, Facebook, and Azure AD while maintaining custom UI
- Implement JWT tokens in httpOnly cookies (no refresh tokens in frontend)
- Support MFA with TOTP (Time-based One-Time Password)
- Multi-tenant architecture with dealerId and agencyId association
- Role-based access control with four distinct roles and custom scopes
- Dynamic scope injection using AWS Lambda pre-token generation trigger
- Configuration management through AWS SSM Parameter Store
- Secure token handling with proper expiration and rotation
- Support for custom user attributes and tenant-specific permissions
Design Specifications
- UI/UX Design:
Data Models:
public record UserMetadata
{
public string UserId { get; init; }
public string Email { get; init; }
public string Role { get; init; } // admin, agency, grouphead, dealer
public string? ConsumerId { get; init; }//dealerid/agencyid
public List<string> CustomScopes { get; init; } = new();
public bool IsActive { get; init; }
public DateTime CreatedAt { get; init; }
public DateTime LastLogin { get; init; }
}
JWT Claims Structure
public record JwtClaims
{
public string Sub { get; init; } // User ID
public string Email { get; init; }
public string Role { get; init; }
public string? ConsumerId { get; init; }//dealerid/agencyid
public List<string> Scopes { get; init; }
public long Exp { get; init; } // Expiration
public long Iat { get; init; } // Issued at
}
API Interfaces:
| Endpoint | Method | Parameters | Response | Response Status Codes |
|---|---|---|---|---|
/api/auth/login | POST | email (required, string)password (required, string) | AuthResponse | 200, 401, 423, 500 |
/api/auth/social/{provider} | GET | provider (required, string): google/facebook | Redirect URL | 302, 400, 500 |
/api/auth/azure | GET | None | Redirect URL | 302, 400, 500 |
/api/auth/callback | GET | code (required, string)state (optional, string) | Redirect to frontend | 302, 400, 500 |
/api/auth/verify-mfa | POST | session (required, string)mfaCode (required, string) | AuthResponse | 200, 400, 401, 500 |
/api/auth/logout | POST | None (uses httpOnly cookie) | Success message | 200, 400, 500 |
/api/auth/create-mfa | POST | userId (required), mfaType (enum: TOTP, SMS) | MFA secret/QR info | 200, 400,404, 500 |
/api/auth/delete-mfa | DELETE | userId (required) | Success message | 200, 404, 500 |
/api/auth/providers | GET | None | ProvidersInfo | 200, 500 |
/api/user/userProfile | GET | None | User | 200 OK, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error |
/api/user/users | GET | None | List of User | 200 OK, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error |
/api/users | POST | UserRecord | Created user info | 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 500 Internal Server Error |
/api/users/{id} | PUT | id (path param), UserRecord(updated user data) | Updated user info | 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 500 Internal Server Error |
/api/users/{userId} | DELETE | userId (required, string) | Success message | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error |
/api/users/{userId}/status | PATCH | userId (required, string), status (required, enum: ACTIVE/DISABLED) | Updated user info | 200 OK, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error |
- Third-Party Integrations:
Workflow:
┌────────────── ───┐ ┌──────────────────┐ ┌─────────────────┐
│ React App │ │ .NET Backend │ │ AWS Cognito │
│ (Custom UI) │◄──►│ (API Layer) │◄──►│ User Pool │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Pre-Token Gen │
│ │ Lambda │
│ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────────────┐
│ SSM Parameter │ │ Cognito User Attributes │
│ Store │ │ (custom:consumerId, |
| | | custom:scopes, etc.) |
└──────────────────┘ └─────────────────────────┘
SSM Parameter Store Structure:
/myapp/cognito/
├── user-pool-id
├── app-client-id
├── app-client-secret (SecureString)
├── jwt-secret-key (SecureString)
├── scopes/
│ ├── admin: "user.read,user.write,user.delete,agency.read,agency.write,agency.delete,dealer.read,dealer.write,dealer.delete,report.read,report.write,system.admin"
│ ├── agency: "user.read,user.write,agency.read,agency.write,dealer.read,dealer.write,report.read"
│ ├── grouphead: "user.read,user.write,dealer.read,dealer.write,report.read"
│ └── dealer: "user.read,profile.read,profile.write"
├── providers/
│ ├── google/
│ │ ├── client-id
│ │ └── client-secret (SecureString)
│ ├── azure/
│ │ ├── client-id
│ │ ├── client-secret (SecureString)
│ │ └── tenant-id
│ └── facebook/
│ ├── app-id
│ └── app-secret (SecureString)
1. Email/Password Authentication Flow
User → React Login Form → POST /api/auth/login → .NET Backend
→ AWS Cognito SRP Auth → Pre-Token Lambda (SSM + Cognito Attributes)
→ Custom JWT Generation → httpOnly Cookie → React Dashboard
2. Social Login Flow (Google/Facebook)
User → Click Social Login → GET /api/auth/social/{provider}
→ Redirect to Cognito Hosted UI → Provider OAuth → Cognito Callback
→ GET /api/auth/callback → Token Exchange → Pre-Token Lambda(SSM + Cognito Attributes)
→ Custom JWT → httpOnly Cookie → Redirect to Frontend
3. Azure AD Federated Login Flow
User → Click Azure Login → GET /api/auth/azure
→ Redirect to Cognito → SAML with Azure AD → Cognito Callback
→ Token Processing → Pre-Token Lambda → JWT Generation
→ httpOnly Cookie → Frontend Redirect
Development Tasks & Estimates
| No | Task Name | Estimate (Hours) | Dependencies | Notes |
|---|---|---|---|---|
| 1 | SSM Parameter Store Configuration | 4 hours | Task 1 | Parameters and security setup |
| 2 | Pre-Token Generation Lambda Development | 4 hours | Task 1, 2 | Nodejs Lambda with scope logic |
| 3 | Cognito User Pool and Identity Providers Setup | 7 hours | Task 1,2 | Google, Facebook, Azure AD config |
| 4 | .NET Backend Authentication Service | 28 hours | Task 1,2,3 | Core auth logic and JWT handling |
| 5 | .NET API Controllers Implementation | 28 hours | Task 6 | Auth endpoints and middleware |
| 6 | MFA Implementation (Backend) | 14 hours | Task 6,7 | TOTP setup and verification |
| 7 | Integration Testing | 14 hours | All tasks | End-to-end testing |
| 8 | Total | 99 hours | - | ~7 weeks for 1 developer |
Testing & Quality Assurance
Unit Tests:
- Lambda function scope generation logic
- JWT token validation and claims extraction
- SSM Parameter Store service methods
- Authentication service methods
- Authorization middleware functionality
Integration Tests:
- Complete OAuth flows for each provider (Google, Facebook, Azure AD)
- End-to-end authentication with MFA
- Token refresh and expiration handling
- Cross-browser compatibility testing
- Multi-tenant scope isolation testing
- Cognito trigger integration testing
Acceptance Criteria:
- ✅ Users can authenticate using email/password, Google, Facebook, and Azure AD
- ✅ Custom React UI is used for all authentication flows (no Cognito hosted UI)
- ✅ JWT tokens are properly secured in httpOnly cookies
- ✅ MFA is enforced for all users with TOTP support
- ✅ Role-based access control works with proper scope enforcement
- ✅ Multi-tenant isolation is maintained (users only access their dealer/agency data)
- ✅ Audit logs capture all authentication events
- ✅ Session management handles token expiration gracefully
- ✅ Configuration is managed through SSM Parameter Store
- ✅ System handles concurrent authentication requests efficiently
Testing Tools:
- Jest for React component testing
- xUnit for .NET unit testing
- Cypress for end-to-end testing
- Postman for API integration testing
- AWS CloudFormation for infrastructure testing
- SonarQube for code quality analysis
Deployment Considerations
Configuration Changes:
- Environment-specific SSM parameters
- Cognito callback URLs for different environments
- CORS configuration for React frontend
- JWT secret rotation strategy
- Lambda function environment variables
Rollout Plan:
- Phase 1: Deploy infrastructure (Cognito, Lambda)
- Phase 2: Deploy backend services with feature flags
- Phase 3: Deploy frontend with authentication disabled
- Phase 4: Enable authentication features progressively
- Phase 5: Full rollout with monitoring and alerting
Infrastructure as Code:
# AWS CloudFormation/CDK deployment
Resources:
- CognitoUserPool
- CognitoIdentityProviders
- LambdaPreTokenGeneration
- SSMParameters
- IAMRoles and Policies
- CloudWatch Log Groups
Risks & Mitigations
| Risk | Impact | Likelihood | Mitigation Strategy |
|---|---|---|---|
| OAuth provider rate limits | High | Medium | Implement exponential backoff and caching |
| JWT token compromise | High | Low | Short token expiry, secure cookie settings |
| Lambda cold start delays | Medium | Medium | Provisioned concurrency for Lambda |
| SSM parameter store limits | Medium | Low | Parameter hierarchies and batch operations |
| Cognito service limits | High | Low | Monitor usage quotas and request increases |
| Cross-browser compatibility | Medium | Medium | Comprehensive browser testing matrix |
| Azure AD configuration errors | High | Medium | Detailed documentation and testing procedures |
| Multi-tenant data leakage | High | Low | Strict scope validation and audit logging |
Security Considerations
Authentication Security:
- JWT tokens in httpOnly, secure, SameSite cookies
- PKCE (Proof Key for Code Exchange) for OAuth flows
- Strong password policies enforced by Cognito
- MFA mandatory for all users
- Session timeout and proper logout handling
Authorization Security:
- Principle of least privilege for all scopes
- Tenant isolation through custom claims
- Server-side authorization validation
- Audit logging for all access attempts
- Regular security assessments
Infrastructure Security:
- SSM Parameter Store encryption at rest
- Lambda function VPC isolation
- CloudWatch log retention policies
- IAM roles with minimal required permissions
Monitoring & Alerting
Key Metrics:
- Authentication success/failure rates
- Token generation latency
- Lambda function execution duration
- SSM parameter access patterns
Alerts:
- Failed authentication attempts exceeding threshold
- Lambda function errors or timeouts
- Unusual scope access patterns
- Token expiration issues
Review & Approval
(Include a section for review and approval by stakeholders.)
-
Reviewer:
Ayon Das -
Approval Date:
2025-09-23
Notes
(Add any additional notes or considerations related to the feature development here.)