OpenConextApps/apis — pull request #12 by toddfast (2013-04-14 06:46:44+00:00)
Title: Missing auth state fix

My custom authenticator needs to check credentials with an external system. If the credentials are incorrect, the login page has to be reloaded to give the user another try.

Perhaps there is a better way to do this, but I had my authenticator call `processInitial()` again when the authentication failed, which I thought should just present the login form again.

Recall that embedded with the login form is a hidden input, `AUTH_STATE`. This value is created when the login form is first shown, and is stashed in the request attributes during the first request, where it is picked up by the JSP.

However, when reloading the login form the second time, there is no `AUTH_STATE` request attribute (it is a request parameter now, having been submitted by the login form), and showing the login form again results in an empty value for `AUTH_STATE`, which is eventually passed into the `authenticate()` method in my custom authenticator. This empty value prevents the authenticator from being able to proceed to showing the user consent with an NPE; basically, everything falls apart without access to the auth state.

It seems that the correct behavior would be to provide the `authenticate()` method in the authenticator with the auth state by looking first in the request attributes (for the first login request), and then second in the request parameters (for subsequent requests). Following this approach fixes the problem, and I can call `processInitial()` as many times as needed.

Again, maybe my authenticator is doing something wrong in trying to show the login form again, so advice would be appreciated. In the meantime, here is the fix described above.

By the way, the custom authentication flow is pretty messy and not easy to understand or override. This area could be significantly improved to have a much cleaner API and lifecycle, especially since it will probably always be necessary. I have some ideas and would be happy to elaborate further.