Discarding cookie authenticator is not working when request comes from a proxy (Silhouette 5.0.1)

Hello,

The system works fine if I access directly to the instance, but if the request comes from a proxy (with redirects on) the discarding of the cookie authenticator does not work and leaves an empty cookie instead of completely removing it.

The Logout functions:

  def signOut = silhouetteCookie.SecuredAction.async {
    implicit request =>
      silhouetteCookie.env.eventBus.publish(LogoutEvent(request.identity, request))
      silhouetteCookie.env.authenticatorService.discard(request.authenticator, Redirect(routes.HomeCtrl.index))
  }

The cookies when the logout is called are (removed characters for easy reading):

Cookie,PLAY_SESSION=eyJhbGciOi...; msbUserId=1-0971a8aa38f8570e28....)

When the “Redirect” happens I get the following headers (being printed in a Play filter)

When the instance is called directly:

Cookie,PLAY_SESSION=eyJhbGciOi...)

And when the instance is called from a proxy server

Cookie,PLAY_SESSION=eyJhbGciOi...; msbUserId=)

The msbUserId cookie stays there, empty, instead of being removed, then silhouette outputs an error because it cannot decrypt the cookie.

I haven’t been able to figure out why this is happening.

Any ideas are appreciated, thanks in advance.

Hello,

Silhouette uses Play’s functionality to discard cookies. Could you please test this with plain Play functionality for a test cookie?

Best regards,
Christian

Hi, thanks for the quick reply.

I’ve tested it and yes it happens with plain Play’s functionality.

def signOut = Action { implicit request =>
  Redirect(routes.HomeCtrl.index).discardingCookies(DiscardingCookie("PLAY_SESSION"), DiscardingCookie("msbUserId"))
}

The result of the above with the same 2 cookies is:

 (Cookie,PLAY_SESSION=; msbUserId=)

This does not seem normal and it only happens if the request goes thru a reverse proxy, I’ve analyzed the headers but didn’t see anything suspicious.

I try and post this in the Play’s message boards instead, thanks.

In the meantime, wouldn’t it make sense for silhouette to ignore an empty cookie?

Also, I leave here the stacktrace outputted by Silhouette:

Cookie failed message authentication check [play.api.mvc.DefaultUrlEncodedCookieDataCodec in play-dev-mode-akka.actor.default-dispatcher-23]

[Silhouette][cookie-authenticator] Invalid cookie signature [c.m.p.s.i.a.CookieAuthenticatorService in scala-execution-context-global-511]

com.mohiva.play.silhouette.api.exceptions.AuthenticatorException: [Silhouette][cookie-authenticator] Invalid cookie signature
        at com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator$.unserialize(CookieAuthenticator.scala:125)
        at com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticatorService.$anonfun$retrieve$2(CookieAuthenticator.scala:214)
        at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:302)
        at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
        at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.mohiva.play.silhouette.api.exceptions.CryptoException: [Silhouette][JcaSigner] Invalid message format; Expected [VERSION]-[SIGNATURE]-[DATA]
        at com.mohiva.play.silhouette.crypto.JcaSigner.fragment(JcaSigner.scala:81)
        at com.mohiva.play.silhouette.crypto.JcaSigner.extract(JcaSigner.scala:60)
        at com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator$.unserialize(CookieAuthenticator.scala:123)
        ... 9 common frames omitted

Wouldn’t the previous statement make more sense?

I posted the problem in the Play message forum but no reply still.

I think it doesn’t make sense. It’s an error which Silhouette should show.

I do not think it’s an issue with Silhouette or Play itself. I think it’s more an error with your proxies.

Hi,

Yeah, you’re probably right. If the traffic doesn’t go through the proxy, everything works.

But non the less, I haven’t gotten a response from Play on how this can happen, i.e., In what scenario is Play Framework deleting the content of a cookie but leaving it empty after running discardingCookies…

Either way, the problem is not with silhouette. Thanks.