16 KiB
adas-core.Authentication — Security & Identity Abstractions
The Authentication Layer of the ADAS Core platform.
Provides a strategy-pattern abstraction for authentication, JWT token management, user identity resolution, and role-based authorization. This layer defines who can access the system, delegating how credentials are validated to concrete strategy projects (LdapLogin,LocalLogin).
Table of Contents
- Overview
- Responsibilities
- Project Structure
- Dependencies
- Authentication Strategy Pattern
- Core Contracts
- Token Lifecycle
- Authorization Attributes
- Registration Extensions
- Extensibility
- Design Rules
Overview
adas-core.Authentication is the security abstraction layer of the ADAS platform. It establishes the contracts and shared infrastructure for identity management without committing to any single credential store or validation mechanism.
Key characteristics:
- Strategy Pattern — Authentication is abstracted behind
ILoginService; concrete strategies (LDAP, Local DB, future OAuth) are implemented in separate satellite projects. - JWT-Native — All sessions are represented as signed JWT tokens with refresh-token support.
- Role-Based Access Control — Authorities (roles/permissions) are modeled in the Domain layer and managed through
IAuthorityService. - Framework-Agnostic Contracts — Authentication contracts depend only on
DomainandApplication, never on Infrastructure or Host concerns. - Extensible by Design — New authentication strategies (OAuth 2.0, SAML, OIDC) can be added as new projects implementing
ILoginServicewithout modifying this layer.
Responsibilities
| Concern | What this project does |
|---|---|
| Login Strategy Contract | Defines ILoginService — the universal interface that all concrete login providers must implement. |
| Token Generation | ITokenService issues, serializes, and validates JWT access and refresh tokens. |
| User Identity | IUserService manages user lookup, creation, update, deletion, and association with roles/authorities. |
| Authority Management | IAuthorityService governs role assignment and permission resolution for users. |
| Registration Helper | AuthRegistration provides DI registration helpers consumed by the Host project. |
| Auth Attributes | Custom authorization attributes (AuthorizeRolesAttribute, PermissionAuthorizeAttribute, etc.) for declarative security on controllers. |
| Cross-Cutting Security | Encapsulates token validation parameters, refresh-token rotation logic, and CAS-ticket resolution. |
Project Structure
adas-core.Authentication/
├── Interfaces/ # Core security contracts
│ ├── ILoginService.cs # Universal login strategy contract
│ ├── ITokenService.cs # JWT generation / serialization
│ ├── IUserService.cs # User CRUD + token login / refresh
│ └── IAuthorityService.cs # Role / permission management
├── Models/ # Authentication DTOs / value objects
│ ├── LoginInfo.cs
│ ├── Token.cs
│ └── UciResponse.cs
├── Attributes/ # Declarative authorization attributes
│ ├── AuthorizeRolesAttribute.cs
│ ├── AuthorizeUserByService.cs
│ └── PermissionAuthorizeAttribute.cs
├── RegistrationExtensions/
│ └── AuthRegistration.cs # DI wiring helpers
├── AuthorityService.cs # Concrete authority management
├── UserService.cs # Concrete user identity management
└── adas-core.Authentication.csproj
Dependencies
Downstream References
| Project | Role |
|---|---|
adas-core.Domain |
User, Authorization, UserEnum.LoginMethod, and other identity entities used by contracts. |
adas-core.Application |
PaginationFilter, PaginationResponse, CreateUserWithAuthDto, UpdateUserWithAuthDto DTOs consumed by IUserService. |
Upstream References (projects that depend on this)
| Project | Reason |
|---|---|
adas-core (Host) |
Calls AddAuth() to register IUserService, applies [Authorize*] attributes on controllers, and consumes TokenResult from login endpoints. |
adas-core.LdapLogin |
Implements ILoginService for LDAP / Active Directory. |
adas-core.LocalLogin |
Implements ILoginService for local database credentials. |
adas-core.Test |
Mocks IUserService and ITokenService in unit/integration tests. |
NuGet Packages
| Package | Version | Purpose |
|---|---|---|
System.IdentityModel.Tokens.Jwt |
8.18.0 | JWT token creation, validation, and parsing. |
Microsoft.IdentityModel.Tokens |
8.18.0 | Signing key and token validation parameter abstractions. |
Microsoft.AspNetCore.Http |
2.3.10 | HttpContext consumption in ILoginService overloads. |
Microsoft.AspNetCore.Mvc.NewtonsoftJson |
8.0.27 | MVC attribute compatibility. |
AuditLogs |
1.0.59 | Audit tagging on sensitive identity operations. |
Authentication Strategy Pattern
The layer uses the Strategy Pattern to decouple authentication mechanisms from the core identity logic. The Host selects the appropriate strategy at runtime via configuration.
classDiagram
class ILoginService {
<<interface>>
+Method : LoginMethod
+AllowPassword : bool
+Login(username, password) Task~User~
+Login(context) Task~User~
+Authenticate(username, password) Task~User~
+GetById(id) Task~User?~
+GetByEmail(email) Task~User?~
+GetByUsername(username) Task~User?~
+GetAllUsers() Task~List~User~~
}
class LdapLoginService {
+BindToLdap()
}
class LocalLoginService {
+HashPassword()
}
class FutureOAuthService {
+ExchangeCode()
}
ILoginService <|-- LdapLoginService
ILoginService <|-- LocalLoginService
ILoginService <|-- FutureOAuthService
Strategy Selection
The Host determines which strategy to activate via configuration (Authentication:Scheme):
| Scheme | Implementing Project | Description |
|---|---|---|
Ldap |
adas-core.LdapLogin |
Delegates credential validation to an LDAP / Active Directory server. |
Local |
adas-core.LocalLogin |
Validates credentials against locally stored user records with bcrypt hashing. |
| Future | adas-core.OAuthLogin | Could implement OAuth 2.0 / OIDC without touching this layer. |
Critical Rule: This project defines the strategy contract but contains zero implementation logic for any specific credential store.
Core Contracts
ILoginService — Authentication Strategy Contract
The universal interface implemented by every concrete authentication provider.
public interface ILoginService
{
bool AllowPassword { get; }
UserEnum.LoginMethod Method { get; }
Task<User> Login(string username, string password);
Task<User> Login(HttpContext context);
Task<User> Authenticate(string username, string password);
Task<User?> GetById(ObjectId id);
Task<User?> GetByEmail(string email);
Task<User?> GetByUsername(string username);
Task<List<User>> GetAllUsers();
}
Key design notes:
AllowPasswordsignals whether the strategy supports password-based login (false for certificate-based or token-only strategies).Methoddiscriminates the strategy so the Host can route to the correct implementation.Login(HttpContext)enables context-aware login (e.g., certificate extraction, client assertions).
ITokenService — JWT Management
Responsible for issuing, serializing, and validating tokens without knowing user details.
public interface ITokenService
{
int RefreshTokenValidityInDays { get; }
SecurityToken? GetToken(string username, List<Claim> claims);
string GetRefreshToken();
string Serialize(SecurityToken token);
}
IUserService — Identity Management
The central identity orchestrator. Combines authentication, token lifecycle, and user administration.
Key operations:
| Area | Methods |
|---|---|
| Authentication | Login, GetUser, Authenticate |
| Token Lifecycle | GenerateJwt, RefreshToken, ValidateToken, LoginWithAccessToken, LoginWithGivenAccessToken |
| User CRUD | GetAll, GetUserById, GetUserByUserName, GetUserByName, CreateUser, CreateNewUserByRequest, CreateNewUserWithAuthorities, UpdateUserWithAuthorities, UpdateUsersByRequest, UpdateUserPassword, DeleteUser, GetPaginatedUsers |
| CAS Integration | GetUserByCasTicket |
IAuthorityService — Role-Based Access Control
Manages the link between users and their permissions.
public interface IAuthorityService
{
Task<List<Authorization>> GetUserAuthorities(ObjectId userId);
Task<List<Authorization>> GetAllAuthorities();
void CreateNew(string roleName, ObjectId userId);
Task InsertOne(Authorization authorization);
Task updateOne(Authorization authorization);
Task<bool> DeleteAuthoritiesForUser(ObjectId id);
Task<Authorization?> CreateNewUserAuthority(Authorization authorization);
Task<bool> DeleteUserAuthority(ObjectId userAuthorityIdParsed);
Task<Authorization?> EditUserAuthority(Authorization authorization);
}
Token Lifecycle
The authentication layer manages the complete lifecycle of bearer tokens:
[User Credentials] --> [ILoginService.Authenticate] --> [User]
|
v
[IUserService.GenerateJwt]
|
+---------------------------+---------------------------+
| |
v v
[Access Token] [Refresh Token]
(short-lived) (long-lived)
| |
v v
[API Requests] [IUserService.RefreshToken]
|
v
[New Access Token]
| Token Type | Expiration | Usage |
|---|---|---|
| Access Token | Configurable (typically 15–60 min) | Sent in Authorization header for every API call. |
| Refresh Token | RefreshTokenValidityInDays (configurable) |
Exchanged silently for a new access token without re-entering credentials. |
Authorization Attributes
Declarative security attributes are defined in this layer and applied on controllers in the Host project.
| Attribute | Purpose | Placement |
|---|---|---|
AuthorizeRolesAttribute |
Restricts access to users with one or more specified roles. | Class or method level. |
AuthorizeUserByService |
Allows service-scoped authorization (e.g., a service account accessing specific units). | Method level. |
PermissionAuthorizeAttribute |
Fine-grained permission checks beyond role membership. | Method level. |
All attributes derive from ASP.NET Core authorization infrastructure but are customized to integrate with the
IAuthorityServicepermission model.
Registration Extensions
AuthRegistration.cs provides a centralized helper for wiring authentication services into the Host DI container:
public static class AuthRegistration
{
public static void AddAuth(this IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IUserService, UserService>();
serviceCollection.AddSingleton<Lazy<IUserService>>(provider =>
new Lazy<IUserService>(provider.GetRequiredService<IUserService>));
}
}
The Host project calls builder.Services.AddAuth() during startup, which in turn registers:
IUserServicesingleton- Lazy wrapper for deferred resolution
ITokenServiceandIAuthorityServiceconcrete implementations
Concrete strategy projects (LdapLogin, LocalLogin) then register their own ILoginService implementations, completing the pipeline.
Extensibility
Adding a New Authentication Strategy
To introduce a new mechanism (e.g., OAuth 2.0, SAML, certificate-based):
- Create a new project (e.g.,
adas-core.OAuthLogin). - Reference
adas-core.Authenticationandadas-core.Domain. - Implement
ILoginServicewith the new credential validation logic. - Register the implementation in the Host project's
Program.csalongsideAddAuth(). - Configure the strategy selector in
appsettings.json.
No changes to adas-core.Authentication are required. The Host simply resolves the correct ILoginService implementation based on runtime configuration.
Supported Future Strategies
| Strategy | Feasibility | Notes |
|---|---|---|
| OAuth 2.0 / OIDC | High | Implement ILoginService with code exchange flow. |
| SAML 2.0 | Medium | Parse SAML assertions, map to User entity. |
| Certificate-Based (mTLS) | Medium | Read client certificate from HttpContext, validate chain. |
| Kerberos / SPNEGO | Low | Possible but requires Windows domain integration. |
Design Rules
- No Credential Logic in Contracts — This project defines interfaces, models, and attributes. It never implements LDAP binds, password hashes, or database queries.
- Strategy Isolation — Each authentication mechanism lives in its own project implementing
ILoginService. No conditional logic selecting between strategies insideAuthentication. - Domain Dependency Only — References only
adas-core.Domainandadas-core.Application. No reference to Infrastructure, Modules, or Host. - Token Immutability — Once issued, a JWT is self-contained. The token service signs it; validation relies on signature alone, avoiding database lookups per request.
- Lazy Resolution —
IUserServiceis wrapped inLazy<T>to defer heavy initialization until first usage. - Audit Awareness — Every mutating identity operation (create user, change password, update authority) must emit an audit event before returning.
- No Hardcoded Secrets — Token signing keys, LDAP server addresses, and refresh-token storage paths come exclusively from configuration; never from source code.
- RBAC Extensibility — Authorities are stored as domain entities. Custom roles can be created dynamically without redeploying the authentication layer.
- Attribute-Driven Security — Controllers declare authorization requirements via attributes; the Host enforces them through policy evaluation. The Authentication layer provides the building blocks, not enforcement logic.
- Consistent Error Semantics — All authentication failures throw or return standard domain exceptions (
UnauthorizedException,TokenException) defined inadas-core.Application.Exceptions.
Back to adas-core Root README