Class JdbcTotpRepository
- All Implemented Interfaces:
TotpRepository
Secrets kept in the server's database, in the cn1_mfa_totp table of
SecuritySchema.
A secret is what an attacker needs to produce a user's codes for good, so it is not stored as it is: each is sealed with AES-GCM under a key the database does not hold, with a nonce of its own stored beside it and the user's name bound in, so a row copied onto another user does not open. Give the key in the configuration, as 32 bytes in base64:
cn1.security.mfa.encryptionKey=... # openssl rand -base64 32
and build the repository with fromConfig(DataSource, Config). Losing the key loses every
enrolment; changing it does the same.
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanConsumes a sign-in code only if the confirmed credential still has the verified secret and its last accepted step is lower.booleanRecords that a code of time stepstepwas accepted, if no code of that step or a later one has been.booleanMarks the credential confirmed, if it is there and was not.booleanConfirms and consumes a code only if the current, unconfirmed credential still has the secret that was verified.booleanForgets the credential.The credential ofusername, or null.static JdbcTotpRepositoryfromConfig(DataSource dataSource, Config config) A repository whose key is the configuration'sENCRYPTION_KEY.voidStores a new, unconfirmed secret forusername, replacing any other.void
-
Field Details
-
ENCRYPTION_KEY
-
-
Constructor Details
-
JdbcTotpRepository
- Parameters:
encryptionKey- 32 bytes
-
-
Method Details
-
fromConfig
A repository whose key is the configuration's
ENCRYPTION_KEY.On a development profile a server without the setting gets a fixed key and says so, so that a laptop needs no secret; anywhere else the setting is required and the server does not start without it.
-
setClock
-
save
Description copied from interface:TotpRepositoryStores a new, unconfirmed secret forusername, replacing any other.- Specified by:
savein interfaceTotpRepository
-
find
Description copied from interface:TotpRepositoryThe credential ofusername, or null.- Specified by:
findin interfaceTotpRepository
-
confirm
Description copied from interface:TotpRepositoryMarks the credential confirmed, if it is there and was not.- Specified by:
confirmin interfaceTotpRepository- Returns:
- whether this call confirmed it
-
advance
Description copied from interface:TotpRepositoryRecords that a code of time step
stepwas accepted, if no code of that step or a later one has been.The test and the change are one step, which is what makes a code good once: of two requests presenting the same code at the same moment, on one server or two, exactly one is told true.
- Specified by:
advancein interfaceTotpRepository- Returns:
- whether this call recorded it
-
confirm
Description copied from interface:TotpRepositoryConfirms and consumes a code only if the current, unconfirmed credential still has the secret that was verified. The comparison and both changes must be atomic, including across servers sharing a database.- Specified by:
confirmin interfaceTotpRepository
-
advance
Description copied from interface:TotpRepositoryConsumes a sign-in code only if the confirmed credential still has the verified secret and its last accepted step is lower. This is one atomic change.- Specified by:
advancein interfaceTotpRepository
-
delete
Description copied from interface:TotpRepositoryForgets the credential.- Specified by:
deletein interfaceTotpRepository- Returns:
- whether there was one
-