Files
2026-06-26 10:29:23 +02:00

346 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
1. [Overview](#overview)
2. [Responsibilities](#responsibilities)
3. [Project Structure](#project-structure)
4. [Dependencies](#dependencies)
5. [Authentication Strategy Pattern](#authentication-strategy-pattern)
6. [Core Contracts](#core-contracts)
7. [Token Lifecycle](#token-lifecycle)
8. [Authorization Attributes](#authorization-attributes)
9. [Registration Extensions](#registration-extensions)
10. [Extensibility](#extensibility)
11. [Design Rules](#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 `Domain` and `Application`, never on Infrastructure or Host concerns.
- **Extensible by Design** — New authentication strategies (OAuth 2.0, SAML, OIDC) can be added as new projects implementing `ILoginService` without 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.
```mermaid
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.
```csharp
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:
- `AllowPassword` signals whether the strategy supports password-based login (false for certificate-based or token-only strategies).
- `Method` discriminates 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.
```csharp
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.
```csharp
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 1560 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 `IAuthorityService` permission model.
---
## Registration Extensions
`AuthRegistration.cs` provides a centralized helper for wiring authentication services into the Host DI container:
```csharp
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:
- `IUserService` singleton
- Lazy wrapper for deferred resolution
- `ITokenService` and `IAuthorityService` concrete 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):
1. **Create a new project** (e.g., `adas-core.OAuthLogin`).
2. **Reference** `adas-core.Authentication` and `adas-core.Domain`.
3. **Implement `ILoginService`** with the new credential validation logic.
4. **Register** the implementation in the Host project's `Program.cs` alongside `AddAuth()`.
5. **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
1. **No Credential Logic in Contracts** — This project defines interfaces, models, and attributes. It never implements LDAP binds, password hashes, or database queries.
2. **Strategy Isolation** — Each authentication mechanism lives in its own project implementing `ILoginService`. No conditional logic selecting between strategies inside `Authentication`.
3. **Domain Dependency Only** — References only `adas-core.Domain` and `adas-core.Application`. No reference to Infrastructure, Modules, or Host.
4. **Token Immutability** — Once issued, a JWT is self-contained. The token service signs it; validation relies on signature alone, avoiding database lookups per request.
5. **Lazy Resolution**`IUserService` is wrapped in `Lazy<T>` to defer heavy initialization until first usage.
6. **Audit Awareness** — Every mutating identity operation (create user, change password, update authority) must emit an audit event before returning.
7. **No Hardcoded Secrets** — Token signing keys, LDAP server addresses, and refresh-token storage paths come exclusively from configuration; never from source code.
8. **RBAC Extensibility** — Authorities are stored as domain entities. Custom roles can be created dynamically without redeploying the authentication layer.
9. **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.
10. **Consistent Error Semantics** — All authentication failures throw or return standard domain exceptions (`UnauthorizedException`, `TokenException`) defined in `adas-core.Application.Exceptions`.
---
<p align="center">
Back to <a href="../README.md">adas-core Root README</a>
</p>