An access token can be obtained using basic authentication with:
POST /api/v1/token
Important
External clients are required to activate a subscription via:
POST /api/v1/clients/{key}/subscriptions
Note
The access token can be validated via:
POST /api/v1/token/status.
Access and refresh tokens can be obtained using:
POST /api/v2/token
-
An OTP can be requested via:
POST /api/v1/otp -
The OTP can be exchanged for access and refresh tokens via:
POST /api/v3/token
Important
To authenticate with OTP, users are required to verify their email via:
POST /api/v1/email/verification/{token}
Note
The access token can be validated via:
POST /api/v1/token/status.
Tip
The access token can be refreshed via:
PUT /api/v2/token
⚙️ Complete API documentation can be found in swagger.json.
SDK: .NET Core 10
Database: SQL Server 2022
ORM: Entity Framework Core
Caching: Redis
Message Broker: RabbitMQ
Additional Libraries: Serilog, Polly, AutoMapper, GoogleAuthenticator
Tests: xUnit, FluentAssertions, Bogus
Note
Database creation and schema management are handled through Entity Framework Core migrations.
Note
Initialization scripts are automatically executed using DbUp.
Important
The API requires running RabbitMQ broker.
Note
The application follows Clean Architecture.
Note
The data access is managed with Repository and Unit of Work patterns.
Note
The token handling mechanism follows the Strategy pattern (SecurityTokenHandler).
- Client credentials are received in the
Authorizationheader using the format:
Basic <base64_encoded_key>:<base64_encoded_secret> - The credentials from the header are decoded.
- A database query is executed to fetch client data using the provided
key. - If the
keyexists, theclient statusis validated. - If the
client statusis acceptable, the system checks for an activesubscription. - If there is an active
subscription, the storedsecretis compared with the provided secret. - If the
secretis valid, thefailed login attempt counteris reset. - An
access token(JWT) is generated, scoped to theclient IDand the applications the client is allowed to access.
Warning
Invalid key or secret results in HTTP status code 401 Unauthorized.
Warning
Invalid client status or missing active subscription results in HTTP status code 403 Forbidden.
Caution
If the failed login attempt counter exceeds the allowed limit, the client status is updated to BLOCKED.
- User
usernameandpasswordare received in the request body. - A database query is executed to fetch user data using the provided
username. - If the
usernameexists, theuser statusis validated. - If the
user statusis acceptable, the providedpasswordis hashed using the same method as the stored one. - The hashed
passwordis compared with the stored password. - If the passwords match, the
failed login attempt counteris reset. - An
access token(JWT) is generated, scoped to theuser ID,username,user roleanduser status. - A
refresh token(JWT) is generated, scoped to theuser ID.
Note
An event is sent when a login attempt is made through a new IP address.
Warning
Invalid username or password results in HTTP status code 401 Unauthorized.
Warning
Invalid user status results in HTTP status code 403 Forbidden.
Caution
If the failed login attempt counter exceeds the allowed limit, the user status is updated to BLOCKED and an alert for login attempt is registered.
- User
usernameandpasswordare received in the request body. - A database query is executed to fetch user data using the provided
username. - If the
usernameexists, theuser statusis validated. - If the
user statusis acceptable, the providedpasswordis hashed using the same method as the stored one. - The hashed
passwordis compared with the stored password. - If the passwords match, the
failed login attempt counteris reset. - A
one-time passwordis generated and saved toRedis. - A message is registered to send the
one-time passwordto the user via the preferred notification provider. - The user receives the
one-time passwordand enters it. - An attempt is made to fetch the
one-time passwordfromRedis. - If the
one-time passwordis valid and not expired, it is deleted fromRedis. - An
access token(JWT) is generated, scoped to theuser ID,username,user roleanduser status. - A
refresh token(JWT) is generated, scoped to theuser ID.
Note
Each one-time password is stored in Redis with an absolute expiration.
Warning
Invalid username or password or one-time password results in HTTP status code 401 Unauthorized.
Warning
Invalid user status results in HTTP status code 403 Forbidden.
Caution
A failed login attempt counter is maintained in Redis per one-time password. If the counter exceeds the allowed limit, the one-time password is deleted.

