On 3/20/17 3:54 AM, Stian Thorgersen wrote:
Let's go with the "page expired" page then,
The
current behavior is "sticky" in that any back button or page refresh
just renders the current Authenticator in the flow. What sucks with
that is that you have to have a cancel button on each page in order to
restart the flow.
but we wouldn't need it for the refresh page would we? That can
just
re-display the same thing again.
Depends on the implementation of flow processing. This was what I was
trying to explain before.
Remember that refresh re-executes the request to original URL. IF you
set cache control headers, back button will also re-execute the
request. With current impl, code is in the URL, so with a refresh or
back button re-execution the runtime knows the request is a bad one, so
it just finds your current place in the flow and re-renders it. Without
a any code in the URL, the runtime would not know whether your POST was
an old POST triggered by a browser button, or if you were posting to the
correct and current Authenticator.
+1 I kinda thought about writing authenticators, but you're right
that
should be made as simple as possible and we should ideally handle all
of this outside the authenticators themselves. Something that would be
impossible if users could step backwards/forwards in the flow as you'd
have to have "roll back" events or something so authenticators could
undo stuff if needed.
You could have a stack and push and pop on it as you went
forwards and
backwards.
On 17 March 2017 at 16:21, Bill Burke <bburke(a)redhat.com
<mailto:bburke@redhat.com>> wrote:
The best user experience would be that the user can click the
back/forward/refresh buttons as they wanted and things would work
as they would expect, i.e. if you're on the OTP page, you could
click the back button and go to the username/password page and
re-enter username password. I didn't implement support for this
approach as its really freakin hard to get right.
The real question is, do we want to support going backwards or
forwards in a flow? If we don't, then there are considerations
and limitations on what we can do for the user experience which I
was trying to get at before. Specifically:
* Is it possible to determine the difference between the back,
forward, or refresh button event?
That is the question I struggled the most with when implementing
auth flow processing.
I'd say we set the bar low and minimally try to provide this
experience:
* If back, forward, or refresh button is pushed, show the "Page
expired" page you suggested before Stian.
Anything different than that will be dependent on the limitations
of the browser and our auth flow implementation.
There's also another type of user experience you aren't
considering that should be involved with the discussion.
Specifically the user experience of writing an Authenticator. You
want the Authenticator development to be simple...you also want to
make sure that its implemented in a way that developers can't make
mistakes and introduce security holes by accident. All this stuff
is tied together which makes the problem really complex.
On 3/17/17 3:45 AM, 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.". Or Back button could just go to the
> start of the flow always.
> * Resubmitting forms will just display the page above
> * 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(a)redhat.com
> <mailto:sthorger@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(a)redhat.com
> <mailto:bburke@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-when-reached-v...
>>
<
http://stackoverflow.com/questions/9046184/reload-the-site-when-reached-v...
>>
>> 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
>
>
>