OAuth 2.0 authentication and rejoining session after browser redirect

I’ve been having a look at the possibility of using OAuth 2.0 to authenticate access to a Xojo Web App using Azure Active Directory. There’s a document that describes the general process at https://docs.microsoft.com/en-us/azure/active-directory/active-directory-protocols-oauth-code.

This is what I’ve got so far:

  1. The user launches the Xojo Web App and, on the default Web page, clicks a “Login” button. This uses ShowURL to redirect the user’s browser to https://login.microsoftonline.com/tenant.onmicrosoft.com/oauth2/authorize, with appropriate parameters in the URL as per the document above. I’m using https://myxojowebappurl.com/special/ as my redirect_uri, so that after the user credentials are accepted on the https://login.microsoftonline.com, the browser is redirected back to Xojo. I’m also including the user’s Xojo Session ID in the “state” parameter.

  2. Once the user credentials are entered and accepted, the browser is redirected back to https://myxojowebappurl.com/special/ (with URL parameters as per document above) and picked up by HandleSpecialURL. I can extract the Azure AD authorization code and the Xojo session ID in the HandleSpecialURL event handler by using “Request.Getparameter”.

  3. So now Xojo has the user’s Session ID, and the Authorization Code from Azure AD. This all works fine. Question is - how do I get the user’s browser to rejoin the Session for which I have the ID, and carry on with the process? Something to do with WebSessionContext I assume?

And a related question - if I’m passing the Xojo Session ID back and forth in the URL like this, might there be negative security implications? And if so, is there a better way of doing this?

Hmmm, maybe I need to go about this in a different way. Perhaps the Authorize page could be loaded into a WebHTMLViewer, and then the URL it redirects to after authentication be somehow extracted. If that were possible it’d be much simpler than attempt number 1 above.

It looks like Mike Cotrone was looking at something similar here: https://forum.xojo.com/19342-htmlviewer-view-url-question. But in that case it looks like he was working with a Desktop App rather than a Web App - the Web version doesn’t have the DocumentComplete event that he’s using.

Any ideas, please?

In principle, if the user connects back to the same URL within the timeOut period, he gets back its session.

I would think you need to do something a long the lines of:

  • store authentication details plus say remote address with a short expiration time out
  • generate some kind of one time key
  • redirect user back to your site with the key
  • if key and other credentials match, expire the key
  • generate a new authentication cookie with a short expiry time out
  • extend the time out on each request
  • if the cookie expires send the user back to authentication process again
    I would not leave it for the session to time out as a default and I would not use a session prior to authentication.

That’s unlikely to be consistently stable. If it takes the user longer than 3 minutes (the default) to find their password and log in, the session will no longer exist. Heck, if the app were running behind a load balancer, they might not be guaranteed to hit the same instance.

I think they should? As long as the proxy cookie containing the instance info still exists and is valid?

Assuming that all gets kept with all those redirects :stuck_out_tongue:

From what I understand, the whole point of launching the web app is to click on the login button.

I believe it would be a lot easier to do the login from a simple HTML page, without bothering with the web app, and only connect to the web app after login.

I got it working, by putting code in the “Open” event handler for the Session object, that tests to see if the URL used to call the web app has any parameters.

If there are no parameters, ie https://mywebapp.com, then it uses ShowURL to redirect the user’s browser to the Azure Active Directory sign-in page. If the user is successfully authenticated, their browser is then redirected back to my web app, but this time with parameters, such as https://mywebapp.com?code=JGJITUYT79H6795UFK. (the actual code is much longer)

Now there is a parameter in the URL, so the “Open” event handler for Session receives the Authentication Code. The app then uses HTTPSecureSocket with the POST method to send back the Authentication Code together with the Application Secret and various other info, and finally receives an Access Token which can then be used to request the signed-in user’s name, ID, group membership, etc.

More work to do in the areas of security and error handling but the basics are there. I’ve really enjoyed puzzling this all out, but now my brain hurts and I’m glad it’s the weekend! (it’s 5pm now in the UK)

Thanks all for your help.