scalaauthenticationplayframeworkjwtsilhouette

How to implement multiple Silhouette JWT Authenticators in same application?


There are examples for using multiple types of Authenticators in the same Play Framework application BUT the one I am after is, using 2 JWT authenticators where they have different headerNames, issuer claims and crypter using separate Silhouette environments for each inside the same application.

Update: I have created 2 environments for Silhouette but both signatures are same with different name only, as follows:

trait DefaultEnv extends Env {
  type I = User
  type A = JWTAuthenticator
}

trait CustomEnv extends Env {
  type I = User
  type A = JWTAuthenticator
}

MyModule extends AbstractModule with ScalaModule {
  ...
@Provides
  def provideAuthenticatorService(crypter: Crypter,
                                  idGenerator: IDGenerator,
                                  configuration: Configuration,
                                  clock: Clock): AuthenticatorService[JWTAuthenticator] = {

    val encoder = new CrypterAuthenticatorEncoder(crypter)

    new JWTAuthenticatorService(JWTAuthenticatorSettings(
      fieldName = configuration.underlying.getString("silhouette.authenticator.headerName"),
      issuerClaim = configuration.underlying.getString("silhouette.authenticator.issuerClaim"),
      authenticatorExpiry = FiniteDuration(configuration.underlying.getLong("silhouette.authenticator.authenticatorExpiry"), "seconds"),
      sharedSecret = configuration.underlying.getString("application.secret")

    ), None, encoder, idGenerator, clock)
  }
}

This actually provides the same AuthenticatorService, how to provide different AuthenticatorService for different named environment while they both are actually AuthenticatorService[JWTAuthenticator]?


Solution

  • Finally managed to work to allow 2 JWTAuthenticators in a single play silhouette application: AuthenticatorService[JWTAuthenticator] and another

    CustomAuthenticatorService[CustomJWTAuthenticator]
    

    with Environment and CustomEnvironment existing together

    with Silhouette[DefaultEnv] and CustomSilhouette[CustomEnv]

    where

    trait DefaultEnv extends Env {
      type I = User
      type A = JWTAuthenticator
    }
    
    trait CustomEnv extends Env {
      type I = User
      type A = CustomJWTAuthenticator
    }
    

    The requirement was to allow 2 different sets of apis to 2 different clients of same backend service where the jwt tokens for one set of apis can't be used to authenticate another set of apis even inside the same controller. This solution was implemented this way to prevent breaking the models or codebase for 2 different clients while they use the same database and the event bus.