Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IW OAuth2 Question
#1
I am currently trying to integrate the new OAuth2 protocol into my project, but I am facing difficulties in finding the correct approach. Typically, when a user navigates to our web address, I check in the "IWServerControllerBaseGetMainForm" method if they have a cookie set, indicating they are already logged in and have chosen to stay logged in.

There are two possible scenarios:

  1. If the cookie is not found or has expired, I set the "vMainForm" to the login form, "TfrmLogin", and prompt the user to log in again.
  2. If the cookie is present and valid, I set the "vMainForm" to the user menu, "TformUserMenu", and the user is presented with the main menu without having to log in again.
With the implementation of OAuth2, I want to achieve the same functionality. Specifically, I want to display a "Login with Google" button on the login page. If the user logs in successfully using their Google credentials, I want to avoid showing them the login page again in future sessions.

My question is, how can I check in the server controller whether the user is already logged in using their Google credentials so that I can set the "vMainForm" accordingly in "IWServerControllerBaseGetMainForm"?

Thanks!
Reply
#2
Hi Ioan,

This was something that I considered while I was developing it. The general way to handle this is to save a second cookie in the browser and save the user data on your server (it could be even a local file but ideally in your database). This cookie has a much longer expiration date, let's say a few days. If the cookie exists when you receive the first request, you should use it to retrieve the user information on the Database and bypass the login altogether.

I'll see if I can put together some code to show how it is done.
Reply
#3
For the sake of keeping this conversation public, so other people can benefit from it, I'll post here some information that Ioan and I exchanged via e-mail:

First, Ioan pointed me out this SO post where an user has a similar problem:

https://stackoverflow.com/questions/3594...cess-token


Then, this was basically my response:


Quote:The question that you pointed out has a slightly different nature. In that question case, they are interested in finding out if the token abc123 was actually issued granting access to joe@doe.com, because in that example the user is building an API which has no control over the authorization code request. The token is received in every request and needs to be checked.


In our case, the authorization code request is always done by IntraWeb itself, so you can always know whether a received token is valid or not for user joe@doe.com, as long as you keep this information stored somewhere (and you're able to retrieve it even if the session expires or application restarts, thus a database is ideal).
So, in theory, we don't need to validate a token (i.e. check if the token is a valid one or a forged one) because we just need to compare it against the tokens that we have already requested/received ourselves.

However, I understand your problem. It could be summarized like this:
1) The user logs into your application for the first time (so we have now a valid token abc123 for joe@doe.com)
2) In the following hours or days the user could
  2a) Log off from his google account on that device, or
  2b) Revoke permission for your application to access his private profile/data

If the user does that while his IW session is still active, there is basically nothing that we can do, so his access is considered valid until the current session expires. In all subsequent accesses (i.e. after his first session expired), there are 2 possible ways of handling the access authorization:

a) You ignore (2a) and (2b) events above and continue to grant access to your application as long as the user doesn't explicitly log off from it. In this case you should remove the "access cookie" (the cookie which relates to the access token that I mentioned in my previous email). Then, next time the user tries to log in, it will be prompted again with the Google login. This is how some applications handle this.

b) Every time the user comes back to your application you validate the existing access token (that you saved somewhere and retrieved based on the access cookie received from the user browser) and, if the access token is valid, you can grant access to that user.

As I understood from your request, you would likely go with option (b).

The problem with option (b) above is that OAuth access tokens have a very short life, in general only 1 hour (some APIs allow certain flexibility but it won't cover our needs here, I'm afraid). So, let's say that an access token is obtained now, and 4 hours later the user comes back for a new session. When verified against google API, this token will be rejected with an "invalid_value" error message, which is not enough for our needs either. For instance, in some APIs there is no way to differentiate a fake access token from a legitimate, although expired one.

The solution here, I believe, would be handled in 2 steps:

i) Try to validate the access token using the token info endpoint (or the graph endpoint on Azure). If the access token is not expired, the access will be granted and the authorization process is done. Otherwise, if the access token is not valid (expired, invalid, whatever) we:

ii) Request a new access token from the token endpoint as we did in the first user access, however without requesting the user to explicitly grant access. Both Google and Azure APIs support the "passive" consent, such that the new access token will be generated if the user has previously granted access to that application using that browser/device and the user is currently logged in to his Google or Microsoft account.


Having said that, in the next release we are extending the OAuth support even further, including Facebook API and other features that will allow to handle case (2) above easily.

We are also re-writing the demo application to be a comprehensive one, showing how to deal with this issue.

Cheers
Reply
#4
I believe this will work really well.
Reply
#5
Hi Alexandre,
I have implemented the new OAuth features in my application, and overall, everything is functioning well. However, I am encountering some issues still with the main form. Let's consider the following scenario:

1. When a user is not logged in, they are presented with a login/password form, which also offers the option to log in with Google. At this point, the main form has already been assigned (login form), and the user session has been created.
2. If the user chooses to log in with Google, the application goes through the entire login process, including saving the cookie and storing the relevant information in the database.
3. Here lies the problem: even after successfully logging in with Google, the login form continues to be displayed to the user. Since the IWServerControllerBaseGetMainForm event no longer fires (and no event fires in the login form, except the IWAppFormRender), I am unable to proceed to the next form, the user menu.

Now, if the user closes the browser and starts a new session, I can check whether the user has the cookie with the token hash and set the main form accordingly. However, I am specifically referring to the situation immediately after the user clicks "log me in with Google." I am unsure how to advance to the next form, which is the user menu.
Reply
#6
I'll try to change the demo application accordingly and get back to you on this, Ioan.

Hold on
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)