A Java library for Macaroons.
The aim of this library is to provide an easy-to-use, yet versatile (e.g., support for structural caveats) library for developers.
We now use GitHub packages instead of JitPack.
String hintTargetLocation = "https://google.com";
byte[] macaroonIdentifier = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);
String macaroonSecret = "A secret, only known to the target location";
Macaroon macaroon = new SimpleMacaroon(macaroonSecret, macaroonIdentifier, hintTargetLocation);
VerificationContext context = new VerificationContext();
HashSet<VerificationContext> validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() >= 1);
byte[] firstPartyCaveatIdentifier = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);
// Create a custom FirstPartyCaveat subclass and define its verification process.
FirstPartyCaveat timeConstraint = new FirstPartyCaveat(firstPartyCaveatIdentifier) {
@Override
protected void verify(@NotNull Macaroon macaroon, @NotNull VerificationContext context) throws IllegalStateException {
/*
macaroon: the Macaroon instance that is being verified.
context: the context in which the caveat should hold.
*/
context.addRangeConstraint("time", Pair.of(5, 10));
}
};
macaroon.addCaveat(timeConstraint);
validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() >= 1);
context = new VerificationContext();
context.addRangeConstraint("time", Pair.of(11, 15));
/*
No possible solutions here: context only valid in 'time' range 11 - 15, while the constraint is only valid between 5 - 10.
There is no overlapping between the two ranges.
*/
validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() == 0);
String thirdPartyCaveatRootKey = "Another secret, shared with the third-party";
byte[] thirdPartyCaveatIdentifier = "user is Alice";
String hintDischargeLocation = "https://oauthprovider.com";
ThirdPartyCaveat thirdPartyCaveat = new ThirdPartyCaveat(thirdPartyCaveatRootKey, thirdPartyCaveatIdentifier, hintDischargeLocation);
macaroon.addCaveat(thirdPartyCaveat);
macaroon.verify(macaroonSecret, new VerificationContext()); // Exception thrown: no discharge Macaroon bound.
// You can add additional caveats to the discharge Macaroons, but we are not doing that here.
Macaroon dischargeMacaroon = new SimpleMacaroon(thirdPartyCaveatRootKey, thirdPartyCaveatIdentifier, hintDischargeLocation);
macaroon.bindMacaroonForRequest(dischargeMacaroon);
validContexts = macaroon.verify(macaroonSecret, new VerificationContext());
assert(validContexts.size() >= 1);
Found a bug, problem, ... or do you have a question about this library?
Do not hesitate to contact me as soon as possible!