public class KeyBasedPersistenceTokenService extends Object implements TokenService, InitializingBean
TokenService
that is compatible with clusters and
across machine restarts, without requiring database persistence.
Keys are produced in the format:
Base64(creationTime + ":" + hex(pseudoRandomNumber) + ":" + extendedInformation + ":" + Sha512Hex(creationTime + ":" + hex(pseudoRandomNumber) + ":" + extendedInformation + ":" + serverSecret) )
In the above, creationTime
, tokenKey
and
extendedInformation
are equal to that stored in Token
. The
Sha512Hex
includes the same payload, plus a serverSecret
.
The serverSecret
varies every millisecond. It relies on two static
server-side secrets. The first is a password, and the second is a server integer. Both
of these must remain the same for any issued keys to subsequently be recognised. The
applicable serverSecret
in any millisecond is computed by
password
+ ":" + (creationTime
% serverInteger
).
This approach further obfuscates the actual server secret and renders attempts to
compute the server secret more limited in usefulness (as any false tokens would be
forced to have a creationTime
equal to the computed hash). Recall that
framework features depending on token services should reject tokens that are relatively
old in any event.
A further consideration of this class is the requirement for cryptographically strong
pseudo-random numbers. To this end, the use of SecureRandomFactoryBean
is
recommended to inject the property.
This implementation uses UTF-8 encoding internally for string manipulation.
Constructor and Description |
---|
KeyBasedPersistenceTokenService() |
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet() |
Token |
allocateToken(String extendedInformation)
Forces the allocation of a new
Token . |
void |
setPseudoRandomNumberBytes(int pseudoRandomNumberBytes) |
void |
setSecureRandom(SecureRandom secureRandom) |
void |
setServerInteger(Integer serverInteger) |
void |
setServerSecret(String serverSecret) |
Token |
verifyToken(String key)
Permits verification the <
Token.getKey() was issued by this
TokenService and reconstructs the corresponding Token . |
public Token allocateToken(String extendedInformation)
TokenService
Token
.allocateToken
in interface TokenService
extendedInformation
- the extended information desired in the token (cannot be
null
, but can be empty)TokenService.verifyToken(String)
at any future
time.public Token verifyToken(String key)
TokenService
Token.getKey()
was issued by this
TokenService
and reconstructs the corresponding Token
.verifyToken
in interface TokenService
key
- as obtained from Token.getKey()
and created by this
implementationnull
if the token was not issued by this
TokenService
public void setServerSecret(String serverSecret)
serverSecret
- the new secret, which can contain a ":" if desired (never being
sent to the client)public void setSecureRandom(SecureRandom secureRandom)
public void setPseudoRandomNumberBytes(int pseudoRandomNumberBytes)
pseudoRandomNumberBytes
- changes the number of bytes issued (must be >= 0;
defaults to 256)public void setServerInteger(Integer serverInteger)
public void afterPropertiesSet() throws Exception
afterPropertiesSet
in interface InitializingBean
Exception