Table of Contents
1.0 Authentication
1.0.1 AuthenticationService
AuthenticationService Interface
Implementations of the AuthenticationService answer to the following contract:
@ProxyGen
@VertxGen
public interface AuthenticationService {
@Fluent
AuthenticationService createJwtFromProvider(@Nonnull String token, @Nonnull String authProvider,
@Nonnull Handler<AsyncResult<AuthPackage>> resultHandler);
@Fluent
AuthenticationService refresh(@Nonnull String refreshToken,
@Nonnull Handler<AsyncResult<TokenContainer>> resultHandler);
@Fluent
@GenIgnore
default AuthenticationService switchToAssociatedDomain(String domainId, Jws<Claims> verifyResult,
Handler<AsyncResult<TokenContainer>> resultHandler) {
resultHandler.handle(Future.failedFuture(new NotImplementedException()));
return this;
}
@ProxyClose
void close();
}
An implementation is expect to produce JWT’s based on the token received for an external provider as defined by the Provider interface. It should also be able to refresh an outdated token as a result of an incoming refreshToken. Lastly it should have an implementation for switching from one domain to another, generating a new JWT.
The default implementation AuthenticationServiceImpl is whats used by the JWTGenerator class and can also be deployed as a service on the cluster. It is also reliant on Redis and expects the following parameter in its config:
{
"redis_host" : "<string>",
"redis_port" : "<integer>" // optional
}
1.0.2 VerificationService
VerificationService Interface
The verification interface is responsible for checking the validity of an incoming JWT and checking for authorization of the indicated request. It is called directly by the JWTReceiver and additional can be deployed as a service on the cluster with its default implementation VerificationServiceImpl. It’s contract is as follows:
@ProxyGen
@VertxGen
public interface VerificationService {
@Fluent
VerificationService verifyJWT(@Nonnull String token, @Nonnull Authorization authorization,
@Nonnull Handler<AsyncResult<VerifyResult>> resultHandler);
@Fluent
VerificationService revokeToken(@Nonnull String token, @Nonnull Handler<AsyncResult<Boolean>> resultHandler);
@Fluent
VerificationService verifyJWTValidity(@Nonnull Handler<AsyncResult<Boolean>> resultHandler);
@Fluent
VerificationService revokeUser(@Nonnull String userId, @Nonnull Handler<AsyncResult<Boolean>> resultHandler);
@Fluent
@GenIgnore
default VerificationService verifyToken(@Nonnull String token, Handler<AsyncResult<Jws<Claims>>> resultHandler) {
resultHandler.handle(Future.failedFuture(new NotImplementedException()));
return this;
}
@Fluent
@GenIgnore
default VerificationService verifyAuthorization(Jws<Claims> claims, Authorization authorization,
Handler<AsyncResult<Boolean>> resultHandler)
throws IllegalAccessException {
resultHandler.handle(Future.failedFuture(new NotImplementedException()));
return this;
}
@ProxyClose
void close();
}
The default implementation is generic in use for all applications in conjunction with the JWTReceiver. It is also reliant on Redis and expects the following parameter in its config:
{
"redis_host" : "<string>",
"redis_port" : "<integer>" // optional
}
It can also be set to dev mode in which case it will verifying without checking validity in redis.
1.0.3 AuthPackageHandler
AuthPackageHandler Interface
This interface is intended to be implemented by the application to handle the final conversion of an external token to an internal JWT, and pass the userprofile to the handler. Its contract is as follows:
public interface AuthPackageHandler {
void processDirectAuth(AuthPackage authPackage, String userId,
Handler<AsyncResult<JsonObject>> resultHandler);
void processOAuthFlow(AuthPackage authPackage, String userId,
String finalUrl, Handler<AsyncResult<JsonObject>> resultHandler);
}
1.0.4 Providers
This section details the various providers supported.
They are all based on the Provider interface for checking an external Token and converting it to either a UserProfile or a payload.
public interface Provider<T> {
void checkJWT(String token, Handler<AsyncResult<T>> resultHandler);
}
1.0.4.1 Facebook
The Facebook provider expects two parameters in its config input. The appId and appSecret of the facebook app that corresponds to the application.
appConfig.getString("faceBookAppId");
appConfig.getString("faceBookAppSecret");
1.0.4.2 Google
This provider verifies google tokens and returns a Google Payload for consumption. It requires an array of valid google oauth ids for login.
appConfig.getJsonArray("gcmIds").getList();
1.0.4.3 Instagram
This provider verifies an incoming token and returns an appropriate UserProfile. It requries an instagram client id and secret as parameters in its configuration.
appConfig.getString("instaClientId");
appConfig.getString("instaClientSecret");
1.1 Authorization
1.1.1 Authorizer
Authorizer Interface
The Authorizer is optional for implementing an authorizer class. It is used by the VerificationServiceImpl.
public interface Authorizer {
boolean isAsync();
boolean authorize(Jws<Claims> claims, String domainIdentifier, Authorization authorization) throws IllegalAccessException;
void authorize(Jws<Claims> claims, String domainIdentifier, Authorization authorization, Handler<AsyncResult<Boolean>> resultHandler);
void block(String domainIdentifier, String userId, Handler<AsyncResult<Boolean>> resultHandler);
}
1.1.2 Authorization Class
Authorization Class
The Authorization class is used for producing a simple auth model.
@DataObject(generateConverter = true)
public class Authorization {
private String model;
private String method;
private String domainIdentifier;
public Authorization() {}
public Authorization(JsonObject jsonObject) {
fromJson(jsonObject, this);
}
public JsonObject toJson() {
return JsonObject.mapFrom(this);
}
public boolean validate() {
return (domainIdentifier != null &&
(domainIdentifier.equals(VALIDATION_REQUEST) || domainIdentifier.equals(GLOBAL_AUTHORIZATION)) ||
(model != null && method != null && domainIdentifier != null));
}
public String getModel() {
return model;
}
@Fluent
public Authorization setModel(String model) {
this.model = model;
return this;
}
public String getMethod() {
return method;
}
@Fluent
public Authorization setMethod(String method) {
this.method = method;
return this;
}
public String getDomainIdentifier() {
return domainIdentifier;
}
@Fluent
public Authorization setDomainIdentifier(String domainIdentifier) {
this.domainIdentifier = domainIdentifier;
return this;
}
public static Authorization global() {
return new Authorization().setDomainIdentifier(VALIDATION_REQUEST);
}
}
1.2 Web Handlers
1.2.1 ApiKeyHandler
ApiKeyHandler
This simple class accepts an apikey as a parameter. When deployed as a handler it will verify if the Authorization HTTP Header contains a key starting with “APIKEY “ and then check equality on the supplied key. If not equal it will fail the routingContext with a 401.
1.2.2 AuthHandler
AuthHandler
This Handler is a default implemenation that leverages the AuthUtils class and the VerificationService. It will check for both ApiKeys and JWT tokens by “Bearer “ prepended token in the Authorization Header.
1.2.3 JWTGenerator
JWTGenerator
This class is used for accepting external tokens for conversion and for the typical Oauth Flow.
OAuth:
returnAuthUrl expects a path parameter called :provider, e.g. google.
public void returnAuthUrl(RoutingContext routingContext) { ... }
public void handle(RoutingContext routingContext) { ... }
Direct Conversion:
This expects two headers set:
- Authorization (The actual Token, prepended with “Bearer “)
- X-Authorization-Provider (Caps Provider, e.g. GOOGLE)
public void directAuth(RoutingContext routingContext) { ... }
Refreshing Tokens:
This expects the token in the Authorization Header, prepended with “Bearer “.
public void refreshFromHttp(RoutingContext routingContext) { ... }
1.2.4 JWTReceiver
JWTReceiver
This class is used for handling incoming JWT’s.
The default handler expects an Authorization class as base64 encoded JSON in a custom header. The default is:
X-Authorization-Type
public void handle(RoutingContext routingContext) { ... }
It can also be used to revoke tokens:
The token should be in the Authorization Header, just as a normal request. This will also revoke the refresh token.
public void revoke(RoutingContext routingContext) { ... }
1.3 AuthUtils
AuthUtils
This class has two public apis that abstract away robust communication with both the AuthenticationService and the VerificationService. If you wish to convert an external token you can call this method:
public AuthUtils convertExternalToken(String token, String provider, Handler<AsyncResult<AuthPackage>> resultHandler) { ... }
If you wish to authorize a request you can call this:
public AuthUtils authenticateAndAuthorize(String jwt, Authorization authorization, Handler<AsyncResult<VerifyResult>> resultHandler) { ... }