use of com.macasaet.fernet.Token in project fernet-java8 by l0s.
the class AuthenticationResource method renewSession.
@Path("/renewal")
@PUT
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public String renewSession(final String sessionToken) {
final Token oldToken = Token.fromString(sessionToken);
// ensure this is a valid token and a non-revoked session
// if valid, extend the life of the session
final Session session = sessionValidator.validateAndDecrypt(keySupplier.get(), oldToken);
if (session != null) {
// the session is valid, generate a new token
// both the old and new tokens are valid, but the old one will expire
// sooner as governed by the Fernet spec
// revoking the session will revoke all associated Fernet tokens
final Key key = keySupplier.get().iterator().next();
final Token newToken = Token.generate(random, key, session.getId().toString());
return newToken.serialise();
}
throw new NotAuthorizedException(Response.status(Status.UNAUTHORIZED).entity("invalid session token").build());
}
use of com.macasaet.fernet.Token in project fernet-java8 by l0s.
the class AuthenticationResource method revokeSession.
@Path("/revocation")
@PUT
@Consumes(MediaType.TEXT_PLAIN)
public void revokeSession(final String sessionToken) {
final Token token = Token.fromString(sessionToken);
// ensure this is a valid token and a non-revoked session
final Session session = sessionValidator.validateAndDecrypt(keySupplier.get(), token);
if (session != null) {
// revoke the session for all associated Fernet tokens
session.revoke();
sessionRepository.revokeSession(session);
}
}
use of com.macasaet.fernet.Token in project fernet-java8 by l0s.
the class SecretInjectionIT method verifyFailedForgery.
/**
* This demonstrates a client who attempts to forge a Fernet token but
* cannot do so without knowing the secret key.
*/
@Test
public final void verifyFailedForgery() {
// given
final SecureRandom random = new SecureRandom();
final Key invalidKey = Key.generateKey(random);
final Token forgedToken = Token.generate(random, invalidKey, UUID.randomUUID().toString());
final String tokenString = forgedToken.serialise();
// when
final NotAuthorizedException result = assertThrows(NotAuthorizedException.class, () -> target("secrets").request().header("X-Authorization", tokenString).get(String.class));
// then
assertThat(result, notAuthorisedMatcher);
}
use of com.macasaet.fernet.Token in project fernet-java8 by l0s.
the class SecretInjectionIT method verifyInvalidTokenReturnsNotAuthorized.
@Test
public final void verifyInvalidTokenReturnsNotAuthorized() throws UnsupportedEncodingException {
// given
final SecureRandom random = new SecureRandom();
final Key key = Key.generateKey(random);
final byte[] plainText = "this is a valid token".getBytes("UTF-8");
final Token validToken = Token.generate(random, key, plainText);
final byte[] cipherText = key.encrypt(plainText, validToken.getInitializationVector());
final Token invalidToken = new Token(validToken.getVersion(), validToken.getTimestamp(), validToken.getInitializationVector(), cipherText, key.sign(validToken.getVersion(), validToken.getTimestamp(), validToken.getInitializationVector(), cipherText)) {
public byte getVersion() {
return (byte) (validToken.getVersion() + 1);
}
public Instant getTimestamp() {
return validToken.getTimestamp().plus(Duration.ofDays(365));
}
public IvParameterSpec getInitializationVector() {
final byte[] validVector = super.getInitializationVector().getIV();
final byte[] invalidVector = new byte[validVector.length + 1];
System.arraycopy(validVector, 0, invalidVector, 0, validVector.length);
invalidVector[validVector.length] = 0;
return new IvParameterSpec(invalidVector);
}
};
// when
final NotAuthorizedException result = assertThrows(NotAuthorizedException.class, () -> target("secrets").request().header("Authorization", "Bearer " + invalidToken.serialise()).get(String.class));
// then
assertThat(result, notAuthorisedMatcher);
}
use of com.macasaet.fernet.Token in project fernet-java8 by l0s.
the class ProtocolBuffersExampleIT method renew.
/**
* Renew a session
*
* @param sessionId the existing session ID
* @param tokenString a current valid Fernet token
* @return a new Fernet token with the updated session state embedded
*/
@PUT
@Path("/api/sessions/{sessionId}/renewal")
public String renew(@PathParam("sessionId") final String sessionId, final String tokenString, @Context final HttpServletResponse servletResponse) {
final Token inputToken = Token.fromString(tokenString);
final Session session = inputToken.validateAndDecrypt(key, validator);
if (!Objects.equals(sessionId, session.getSessionId())) {
throw new BadRequestException("SessionID mismatch.");
}
final Instant lastRenewed = Instant.ofEpochSecond(session.getLastRenewalTime());
if (session.hasLastRenewalTime() && lastRenewed.isAfter(Instant.now().minus(Duration.ofMinutes(1)))) {
// prevent denial-of-service
// if token was renewed less than a minute ago, tell the client to back off
servletResponse.addHeader("Retry-After", "60");
// Too Many Requests: https://tools.ietf.org/html/rfc6585#section-4
throw new WebApplicationException("Try again in a minute", 429);
}
// check session validity in server-side data store
// The token and session are valid, now update the session
final Builder builder = Session.newBuilder(session);
builder.setRenewalCount(session.getRenewalCount() + 1);
builder.setLastRenewalTime(Instant.now().getEpochSecond());
final Session updatedSession = builder.build();
// update session in server-side data store
// store the updated session in a new Fernet token
final Token retval = Token.generate(random, key, updatedSession.toByteArray());
return retval.serialise();
}
Aggregations