[keycloak-dev] Improve back-button and refreshes in authenticators?

Bill Burke bburke at redhat.com
Thu Mar 16 13:37:21 EDT 2017

On 3/16/17 10:50 AM, Marek Posolda wrote:
> On 16/03/17 15:27, Bill Burke wrote:
>> * Hidden field in a form is not a good approach.  Its very brittle 
>> and will not work in every situation.  So huge -1 there.
>> * browser back button is not required to resubmit the HTTP request as 
>> the page can be rendered from cache.  Therefore you couldn't have a 
>> "Page Expired" page displayed when the back button is pressed without 
>> setting the header "Cache-Control: no-store, must-revalidate, max-age=0"
> Maybe we can do some javascript stuff like this: 
> http://stackoverflow.com/questions/9046184/reload-the-site-when-reached-via-browsers-back-button 
> But that would mean that we will need to inject some common javascript 
> stuff into every HTML form displayed by authentication SPI. Could we 
> rely on that?
I don't think this is a good approach as Authenticator develoeprs would 
have to do the same thing.

>> * Furthermore, without some type of code/information within the URL, 
>> you also wouldn't know if somebody clicked the back button or not or 
>> whether this was a page refresh or some other GET request.
> Once we have the cookie with loginSessionID, we can lookup the 
> loginSession. And loginSession will contain last code (same like 
> clientSession now) and last authenticator. Then we just need to 
> compare the code from the loginSession with the code from request. If 
> it matches, we are good. If it doesn't match, it's likely the refresh 
> of some previous page and in that case, we can just redirect to last 
> authenticator.
This is the current behavior, but instead of using a cookie, the "code" 
is stored in the URL.

With only a cookie though and no URL information, you won't know the 
different between a Back Button and a Page Refresh for GET requests.  
For POST requests, you won't be able to tell the differencee between a 
Back Button, Page Refresh, or whether the POST is targeted to an actual 

The more I think about it, things should probably stay the way it 
currently is, with improvements on user experience.  I think we can 
support what Stian suggested with the current implementation.

> Not sure if we also need to track all codes, so we are able to 
> distinct between the "expired" code, and between the "false" code, 
> which was never valid and was possibly used by some attacker for CSRF. 
> Maybe we can sign codes with HMAC, so we can verify if it is "expired" 
> or "false" code without need to track the list of last codes.

This has been done in the past.  Then it was switched to using the same 
code throughout the whole flow, then Stian switched it to changing the 
code throughout the flow.  I don't know if he uses a hash or not.


More information about the keycloak-dev mailing list