Topic on Project:Support desk

Fatal exception thrown - Using OAuth2 Client to implement SSO w/ Azure Active Directory

9
KeyBoardMonkey221 (talkcontribs)

Any help would be most appreciated - I'll really try to explain the problem and its context. Hopefully others can learn from my troubles!!! :)

My objective: Create a company wiki hosted on the cloud where employees can use their logins registered in the Azure Active Directory to access wiki resources.

The Basic Set-up: - Cloud-hosted Azure VM w/ this image:

     > https://bitnami.com/stack/mediawiki/virtual-machine
     > Basically contains an apache2 web server, and an image of mediawiki

- In addition to the base image, the extension OAuth2 Client has been installed following these instructions:

     > https://www.mediawiki.org/wiki/Extension:OAuth2_Client
     > OAuth2 Client is built off this open-source project:     
             > https://github.com/thephpleague/oauth2-client

- Azure Active Directory (AD) with a registered Web app / API


The Encountered Problem: After providing the Azure Active Directory's user credentials (email and password), a `Fatal exception of type "GuzzleHttp\Exception\ConnectException"` is thrown.

Attempted in-depth problem analysis: So after attempting a login, the reply url is as such:

(note: I've randomly changed some values)

http://mywikidomain/Special:OAuth2Client/callback?code=AQABAAIAAACEfexXxjamQb3OeGQ4Gugv1Q04EA_ey_K-rj0okPNekuIB-BakV6Gq_pFBR8lfoaNJSWfK3uie9f88BM4C8vgULYulQtX9wh6LY2U0hACqr8cOz41OqbB9SQm0yqSv1Rhw7Pgri1DDwwS_DY1M1b49WR4qV2siDc_5_YmqG5MB-5xfASoTPjYHhWkN5nJ5FfIcK8KhkKGcOUeDNiTBeWZBcKIEBFVsk_pZjwQ-PFpbDRsbOrJvJGX8nuh2lJJpc00z1wrwFqMu-jVlhC7NTE1D3PZxPQEycvzi4_D7TcewyskXDTMiswr1AdYdCDTf68l8jMKpResRlu6qqWjeOIqsJNryGbPBXkA682AEyy8IiTw9KG1vB45uvh8SMLaPZEuHGsw-knUlt-gNAzMv6upc4-f3BtUe49ezFudsaMoLecKA33qvVFj2f9p9HbzbgK3KNDIJ8hcgipMpIR5__fjFe0XvABbRcVbaE4-HkIqWagfsw_GnNxIl7oxhF9H7-AVBRNAeg19gyPfwzTZmpXLH4LGQ_iZcroxdqcmfvZK3hawx1X2w5RbEo078TXYweBJ4mGMGt6RkMp5iSTv8SpGHXIuYKYfKNX__eG0X9kZN-a6QpN8ctmsvqZ_GA46d0LEF43lcw3RmKIeOc3_CL9QWiTs_hhCscxf4O2aQGugpNyAA&state=79c92d94bd9651231fw9dc06269eb1&session_state=96054b69-edab-4f5e-a583-75e83a440379

So, it is sending back an authorization token, but for some reason, mediawiki failing to proceed to the next step and request an access token, and refresh token with the newly acquired authorization token.

I've tried to check the logs in the Apache2 server, but nothing is added.

Is there a way to change that and get more error info??


Configurations/Changes made:

1. As per the OAuth2 Client instructions, I modified LocalSettings.php. Here, I'll briefly describe what information from the Azure AD I put where (<> contains a pseudo variable):

LocalSettings.php _______________________________________

wfLoadExtension( 'MW-OAuth2Client ')
$wgOAuth2Client['client']['id'] = <Application ID>;
$wgOAuth2Client['client']['id'] = <Key created in AD app registration - basically a hash value>
$wgOAuth2Client['configuration']['authorize_endpoint'] = <Azure AD OAUTH 2.0 AUTHORIZATION ENDPOINT>
$wgOAuth2Client['configuration']['access_token_endpoint'] = <Azure AD OAUTH 2.0 TOKEN ENDPOINT>
$wgOAuth2Client['configuration']['api_endpoint'] = <Azure App registered - App ID URI>

// As per the OAuth2 Client instructions...

$wgOAuth2Client['configuration']['redirect_uri'] = <http://mywikidomain/Special:OAuth2Client/callback>


//scopes not mentioned in OAuth2 Client install instructions

//Was throwing an index error if not set.

//https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code

//According to the above link, when requesting an authorization code, scope is ignored and hence shouldn't matter what it is.

//Got the idea of 'user_impersonation' from the above microsoft docs link - use authorization code... -> successful response -> resource

$wgOAuth2Client['configuration']['scopes'] = 'user_impersonation';


// Defaults from OAuth2 Client NOT sure if needed to be changed

$wgOAuth2Client['configuration']['username'] = 'username';</code>
$wgOAuth2Client['configuration']['email'] = 'email';

LocalSettings.php _______________________________________


2. As the above wasn't working, I tried to look through the source code of oauth2-client made by the phpleague to understand what was going on.

> https://github.com/thephpleague/oauth2-client

I noticed that the version that OAuth2 installs is version 1.4 as my code was different, and oauth2-client is up to 2.4.1, so I checkout into master and pulled the new version. No success.


3. I noticed that the oauth2-client has packages developed for specific providers, including the Azure AD.

> https://github.com/thenetworg/oauth2-azure

Hence, I installed as instructed but no change. I think I have to modify some things, but I have no idea what.


Please let me know if there is any more information you need!!!

MarkAHershberger (talkcontribs)
KeyBoardMonkey221 (talkcontribs)

Thanks Mark for the suggestion, but I actually have already tried that tutorial and in following the instructions, I came across some issues :(


In addition, that tutorial is implementing SSO using the SAML protocol, whereas I'm trying to implement it with the OAuth 2.0 protocol with the hope that if I figure out how to do this, then I'll be able to implement it with other apps.

KeyBoardMonkey221 (talkcontribs)

Just for those that may stumble on this is the future, I've solved the bug and continued to solve more bugs until I made SSO work.


First, flow the simple install instructions here: https://github.com/thenetworg/oauth2-azure


Then from your web applications root directory (my looked like this: /opt/bitnami/apps/mediawiki/htdocs), you'll want to navigate to `extensions/MW-OAuth2Client`.

Here, you'll want to open the file `SpecialOAuth2Client.php`.


In this file, it is defining a class called SpecialOAuth2Client.


Within this class, you'll find a line


$this->_provider = new \League\OAuth2\Client\Provider\GenericProvider (...

We want to change to a provider class that is build just for Azure AD (ie. what we downloaded above). Either create a new private variable like `private _providerOld` (arbitrary variable name) and change the above line to:

$this->_providerOld = new \League\OAuth2\Client\Provider\GenericProvider (...

Or delete the contents of $this->_provider = ...

Creating _providerOld just lets you revert back to what you had before so if these following changes don't go well.

So now, you'll want to do:

$this->_provider = new TheNetworg\OAuth2\Client\Provider\Azure([

              'clientId'      => $wgOAuth2Client['client']['id'],
              'clientSecret'  => $wgOAuth2Client['client']['secret'],
              'redirectUri'   => $wgOAuth2Client['configuration']['redirect_uri']

]);

In addition, under, go to `~/vendor/thenetworg/oauth2-azure/src/Provider` where ~ is the root of your web app.

Here, open `Azure.php`.

On the line public $tenant = 'common' input your active directory's ID instead of common

That did it for me :)

Joelittlejohn (talkcontribs)

Do you think there's any way you could submit a pull request to https://github.com/Schine/MW-OAuth2Client that would allow that extension to support Azure with a simple config option? It seems like the valuable work you have done here would be best included in the extension.

Joelittlejohn (talkcontribs)
MarkAHershberger (talkcontribs)

Thank you for documenting all this!

Viiiwonder (talkcontribs)

Came back to say 'Thank You' for documenting this.

Some additional things I might add:

  1. Just forget about running the git submodule init
  2. When you install oauth2-azure: I ended up with it just installing into the root /vendors folder of my wiki root, and was then accessible to the MWoauth2-client
  3. Probably want to comment out require __DIR__ . '/vendors/oauth2-client/vendor/autoload.php'; in SpecialOAuth2Client.php
  4. The JSON references in LocalSettings.php for $wgOAuth2Client['configuration']['username'] are NOT the typical microsoft/azure keys; instead, the AzureResourceOwner class from oauth2-azure replaces them with some 'friendly' values (oid, given_name, family_name, upn, tid) - I ended up using upn, which returns the email address from Azure - the @ symbol is then a problem (you'll get 'Unable to create user with username:' - I overrode $wgInvalidUsernameCharacters with: $wgInvalidUsernameCharacters = ':'; $wgUserrightsInterwikiDelimiter = '>';
Viiiwonder (talkcontribs)

And then I promptly found PluggableAuth... Probably switching over to that this evening. Well, the journey was fun!

Reply to "Fatal exception thrown - Using OAuth2 Client to implement SSO w/ Azure Active Directory"