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


#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.


#2

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


#3

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

#4

Wouldn’t the previous statement make more sense?

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


#5

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.


#6

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.