Search in sources :

Example 6 with Token

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());
}
Also used : Token(com.macasaet.fernet.Token) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) Key(com.macasaet.fernet.Key) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT)

Example 7 with Token

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);
    }
}
Also used : Token(com.macasaet.fernet.Token) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) PUT(javax.ws.rs.PUT)

Example 8 with Token

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);
}
Also used : SecureRandom(java.security.SecureRandom) Token(com.macasaet.fernet.Token) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) Key(com.macasaet.fernet.Key) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 9 with Token

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);
}
Also used : SecureRandom(java.security.SecureRandom) Token(com.macasaet.fernet.Token) IvParameterSpec(javax.crypto.spec.IvParameterSpec) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) Key(com.macasaet.fernet.Key) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 10 with Token

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();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) Instant(java.time.Instant) Builder(com.macasaet.fernet.example.pb.Example.Session.Builder) BadRequestException(javax.ws.rs.BadRequestException) Token(com.macasaet.fernet.Token) Session(com.macasaet.fernet.example.pb.Example.Session) Path(javax.ws.rs.Path) PUT(javax.ws.rs.PUT)

Aggregations

Token (com.macasaet.fernet.Token)17 Key (com.macasaet.fernet.Key)10 Test (org.junit.Test)9 Path (javax.ws.rs.Path)6 ContainerRequest (org.glassfish.jersey.server.ContainerRequest)6 NotAuthorizedException (javax.ws.rs.NotAuthorizedException)5 SecureRandom (java.security.SecureRandom)3 Consumes (javax.ws.rs.Consumes)3 POST (javax.ws.rs.POST)3 PUT (javax.ws.rs.PUT)3 JerseyTest (org.glassfish.jersey.test.JerseyTest)3 Session (com.macasaet.fernet.example.pb.Example.Session)2 Builder (com.macasaet.fernet.example.pb.Example.Session.Builder)2 FernetToken (com.macasaet.fernet.jaxrs.FernetToken)2 Produces (javax.ws.rs.Produces)2 Instant (java.time.Instant)1 IvParameterSpec (javax.crypto.spec.IvParameterSpec)1 BadRequestException (javax.ws.rs.BadRequestException)1 GET (javax.ws.rs.GET)1 WebApplicationException (javax.ws.rs.WebApplicationException)1