Silhouette 4.0.0 can't retrieve authenticator


#1

Hi, try to upgrade silhouette from version 3 version to version 4.0.0 and when i run my app, at the first request i have this error :

2018-10-19 15:25:44,105 ERROR application  -
com.mohiva.play.silhouette.api.exceptions.AuthenticatorRetrievalException: [Silhouette][session-authenticator] Could not retrieve authenticator
...

Caused by: java.lang.IllegalArgumentException: Illegal base64 character 2d
	at java.util.Base64$Decoder.decode0(Base64.java:714)
	at java.util.Base64$Decoder.decode(Base64.java:526)
	at java.util.Base64$Decoder.decode(Base64.java:549)
	at com.mohiva.play.silhouette.api.crypto.Base64$.decode(Base64.scala:31)
	at com.mohiva.play.silhouette.api.crypto.Base64AuthenticatorEncoder.decode(AuthenticatorEncoder.scala:47)
	at com.mohiva.play.silhouette.impl.authenticators.SessionAuthenticator$.unserialize(SessionAuthenticator.scala:94)
	at com.mohiva.play.silhouette.impl.authenticators.SessionAuthenticatorService$$anonfun$retrieve$3$$anonfun$apply$1.apply(SessionAuthenticator.scala:167)

Have you an idea of what is the problem here ?
Thx for your answers.


#2

It seems that a previous cookie session was present on my browser (from the version 3 of silhouette) but the way is encoded can’t be decoded by the new autthenticator service used (the same anthenticator type and i set Base64 encoder for authenticator).
But instead of discard the previous cookie session, it launch an exception !

Have you an idea to bypass this ?

If i change the play.http.session.cookieName value, it works great !
The problem is i can’t change the http session cookie name like that because i have some client that use my APIs and use this cookie session to build authentication themselves.


#3

So if i understand, if someone connect to my APIs, protected by silhouette, but send a cookie session with bad format, that launch exception in the server. Is that right ?


#4

Yes, the format has changed between the two versions. This exceptions will gone, if all your users have at least logged in once. Yust ignore it.


#5

It is not my experience.
I test it, and i can’t log in because i can’t log out before becasue server launch exception.
I use session cookie and it is sent in all user request, but this cookie have the good format so users are log in but can’t access APP and they can’t logout because server can’t read the authenticator :confused:


#6

I see your point. The problem is, that the Silhouette error handle will not be triggered, because the exception is thrown outside the Future context and the error handler will only catch exceptions from Futures. Have you tried to override the Play error handler to catch the exception and reset the session or to show the login page in case the exception will be thrown? The Play error handler should catch all exceptions.

I know this would be an ugly workarround. But I hardly work on the framework agnostic version of Silhouette and there the authenticator handling has completely changed. So I currently see no point to fix this. Sorry


#7

Yes i handle the exception in the play global ErrorHandler. But I don’t what do with this catch.
How can I reset session without access to authenticator ?


#8

In the error handler you have access to the request:
https://www.playframework.com/documentation/2.5.x/ScalaErrorHandling#Extending-the-default-error-handler

Then you can delete the authenticator from the session:

Ok("Error-Result").withSession(request.session - "your.session.authenticator.key")

https://www.playframework.com/documentation/2.5.x/ScalaSessionFlash#Storing-data-in-the-Session


#9

Yes i wanted to use silhouette API to do that but i find the function discardingCookies to do the job.
Thx for the reply and for the help.


#10

Please note: The discardingCookies method discards a complete cookie. So if you discard the session cookie, then it removes all session values, not only the authenticator. If you do not store any other value in the session, this might be OK. Otherwise you should only remove the authenticator key from session.


#11

Yep. What i want is to force user to re login if he has old cookie. So i send 401 with discard the cookie session and my front listen this to redirect on login page and start with new format session cookie.