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

Stian Thorgersen sthorger at redhat.com
Fri Mar 17 04:40:19 EDT 2017


On 17 March 2017 at 09:22, Marek Posolda <mposolda at redhat.com> wrote:

> Ok, for now just ignoring the browser limitations and fact that
> back/forward doesn't refresh the page automatically for POST requests :)
>
> On 17/03/17 08:45, Stian Thorgersen wrote:
>
> I repeat:
>
> Before we discuss implementation though, let's figure out what the ideal
> user experience would be then figure out how to implement it. What about:
>
> * Refresh just works
>
> * Back button will display a nicer page, something like "Page has expired.
> To restart the login process click here. To continue the login process
> click here.".
>
>
> Yeah, that will be nice for UXP.
>
> Or Back button could just go to the start of the flow always.
>
>
> Regarding UXP, I personally like your previous proposal better. If user
> is deep after confirm many authenticator forms and he accidentally
> clicks back-button, he will need to re-authenticate in all
> authenticators again. Not so great for usability though?
>
>
True - giving the user the option to choose is probably best.


> * Resubmitting forms will just display the page above
>
> If we do any of your previous proposal, user will never see the forms,
>
> which he already submitted? For example if he submitted
> username/password and now is on TOTP page, then after click "back" he will be
> either on the "Page has expired" or start of the flow. The start of the flow usually
> will be username/password form, but flow started from scratch, so it
> won't be resubmitting form, but new submit?
>
> Anyway yes, if some of previous forms is re-submitted, we can display "page is expired" page.
>
> I'm not quite following. Is it possible to prevent the back buttons from
"re-submitting" forms at all? If so that's ideal as you then don't get the
ugly message from the browser that the form is expired.


>
> Marek
>
> * No need to do redirects. Redirects is bad for performance, but also has
> twice the response time which is not good from a usability perspective
>
> Is this the optimal user experience? Or should we do something else?
>
> On 17 March 2017 at 08:44, Stian Thorgersen <sthorger at redhat.com> wrote:
>
>> Can we please get back to discussing what the best user experience is
>> first. Then we can discuss implementations?
>>
>> On 16 March 2017 at 18:37, Bill Burke <bburke at redhat.com> wrote:
>>
>>>
>>>
>>> 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-w
>>> hen-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
>>> Authenticator.
>>>
>>> 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.
>>>
>>> Bill
>>>
>>
>>
>
>


More information about the keycloak-dev mailing list