diff --git a/bin/build-release.sh b/bin/build-release.sh
index 6820c7a5379ed3debf433ad54262d611040e0aac..c1f0314e8deab8e9368bba20a3520f3613989b7c 100755
--- a/bin/build-release.sh
+++ b/bin/build-release.sh
@@ -47,6 +47,7 @@ php "$TARGET/composer.phar" config version "$VERSION" -d "$TARGET"
 php "$TARGET/composer.phar" install --no-dev --prefer-dist -o -d "$TARGET"
 
 # Install external modules
+php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authwindowslive
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-cdc
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-memcookie
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-oauth
diff --git a/composer.json b/composer.json
index ed30be3b5ef7371ca1004f87c45c0307f255c12c..47037914d34af55beebae017a0f15e515df9e1f2 100644
--- a/composer.json
+++ b/composer.json
@@ -41,6 +41,7 @@
         "phpmailer/phpmailer": "^6.0",
         "robrichards/xmlseclibs": "^3.0",
         "simplesamlphp/saml2": "^3.3",
+        "simplesamlphp/simplesamlphp-module-authwindowslive": "^1.0",
         "simplesamlphp/simplesamlphp-module-cdc": "^1.0",
         "simplesamlphp/simplesamlphp-module-memcookie": "^1.2",
         "simplesamlphp/simplesamlphp-module-oauth": "^1.0",
diff --git a/modules/authwindowslive/default-disable b/modules/authwindowslive/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/authwindowslive/default-disable
+++ /dev/null
@@ -1,3 +0,0 @@
-This file indicates that the default state of this module
-is disabled. To enable, create a file named enable in the
-same directory as this file.
diff --git a/modules/authwindowslive/docs/windowsliveid.md b/modules/authwindowslive/docs/windowsliveid.md
deleted file mode 100644
index b80116cf3a7ad20fc55ad1e0ceacb6999e438693..0000000000000000000000000000000000000000
--- a/modules/authwindowslive/docs/windowsliveid.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Using the Windows Live ID authentication source with SimpleSAMLphp
-==================================================================
-This module works around the limitation in Microsoft Online/Azure OIDC implementation of not supplying the OIDC userinfo endpoint.
-Microsoft explains the omission by suggesting that the Graph API can produce anything userinfo would have brought, in place.
-
-Remember to configure `authsources.php`, with both your Client ID and Secret key.
-
-To get an API key and a secret, register the application at:
-
- * <https://msdn.microsoft.com/en-us/library/ff751474.aspx>
- * <https://apps.dev.microsoft.com/>
-
-## Testing authentication
-
-On the SimpleSAMLphp frontpage, go to the *Authentication* tab, and use the link:
-
-  * *Test configured authentication sources*
-
-Then choose the *windowsliveid* authentication source.
-
-Expected behaviour would then be that you are sent to Windows Live ID and asked to login.
-
diff --git a/modules/authwindowslive/lib/Auth/Source/LiveID.php b/modules/authwindowslive/lib/Auth/Source/LiveID.php
deleted file mode 100644
index 1b64be62f09cdfe8cf18762133a34ffaad069342..0000000000000000000000000000000000000000
--- a/modules/authwindowslive/lib/Auth/Source/LiveID.php
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\authwindowslive\Auth\Source;
-
-/**
- * Authenticate using LiveID.
- *
- * @author Brook Schofield, TERENA.
- * @author Guy Halse, TENET.
- * @package SimpleSAMLphp
- */
-class LiveID extends \SimpleSAML\Auth\Source
-{
-    /**
-     * The string used to identify our states.
-     */
-    const STAGE_INIT = 'authwindowslive:init';
-
-    /**
-     * The key of the AuthId field in the state.
-     */
-    const AUTHID = 'authwindowslive:AuthId';
-
-    /** @var string */
-    private $key;
-
-    /** @var string */
-    private $secret;
-
-
-    /**
-     * Constructor for this authentication source.
-     *
-     * @param array $info  Information about this authentication source.
-     * @param array $config  Configuration.
-     *
-     * @throws \Exception In case of misconfiguration.
-     */
-    public function __construct($info, $config)
-    {
-        assert(is_array($info));
-        assert(is_array($config));
-
-        // Call the parent constructor first, as required by the interface
-        parent::__construct($info, $config);
-
-        if (!array_key_exists('key', $config)) {
-            throw new \Exception('LiveID authentication source is not properly configured: missing [key]');
-        }
-
-        $this->key = $config['key'];
-
-        if (!array_key_exists('secret', $config)) {
-            throw new \Exception('LiveID authentication source is not properly configured: missing [secret]');
-        }
-
-        $this->secret = $config['secret'];
-    }
-
-    /**
-     * Log-in using LiveID platform
-     *
-     * @param array &$state  Information about the current authentication.
-     * @return void
-     */
-    public function authenticate(&$state)
-    {
-        assert(is_array($state));
-
-        // we are going to need the authId in order to retrieve this authentication source later
-        $state[self::AUTHID] = $this->authId;
-
-        $stateID = \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
-
-        \SimpleSAML\Logger::debug('authwindowslive auth state id = '.$stateID);
-
-        // authenticate the user
-        // documentation at:
-        // https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-protocols-oauth-code/
-        $authorizeURL = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize'.
-            '?client_id='.$this->key.
-            '&response_type=code'.
-            '&response_mode=query'.
-            '&redirect_uri='.urlencode(\SimpleSAML\Module::getModuleURL('authwindowslive').'/linkback.php').
-            '&state='.urlencode($stateID).
-            '&scope='.urlencode('openid https://graph.microsoft.com/user.read')
-        ;
-
-        \SimpleSAML\Utils\HTTP::redirectTrustedURL($authorizeURL);
-    }
-
-    /**
-     * @param array &$state
-     * @return void
-     * @throws \Exception
-     */
-    public function finalStep(&$state)
-    {
-        \SimpleSAML\Logger::debug(
-            "authwindowslive oauth: Using this verification code [".$state['authwindowslive:verification_code']."]"
-        );
-
-        // retrieve Access Token
-        // documentation at:
-        // https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-protocols-oauth-code/#request-an-access-token
-        $postData = 'client_id='.urlencode($this->key).
-            '&client_secret='.urlencode($this->secret).
-            '&scope='.urlencode('https://graph.microsoft.com/user.read').
-            '&grant_type=authorization_code'.
-            '&redirect_uri='.urlencode(\SimpleSAML\Module::getModuleURL('authwindowslive').'/linkback.php').
-            '&code='.urlencode($state['authwindowslive:verification_code']);
-
-        $context = [
-            'http' => [
-                'method' => 'POST',
-                'header' => 'Content-type: application/x-www-form-urlencoded',
-                'content' => $postData,
-            ],
-        ];
-
-        $result = \SimpleSAML\Utils\HTTP::fetch('https://login.microsoftonline.com/common/oauth2/v2.0/token', $context);
-
-        $response = json_decode($result, true);
-
-        // error checking of $response to make sure we can proceed
-        if (!array_key_exists('access_token', $response)) {
-            throw new \Exception(
-                '['.$response['error'].'] '.$response['error_description'].
-                "\r\nNo access_token returned - cannot proceed\r\n".implode(', ', $response['error_codes'])
-            );
-        }
-
-        \SimpleSAML\Logger::debug(
-            "authwindowslive: Got an access token from the OAuth service provider [".$response['access_token']."]"
-        );
-
-        // documentation at: http://graph.microsoft.io/en-us/docs/overview/call_api
-        $opts = [
-            'http' => ['header' => "Accept: application/json\r\nAuthorization: Bearer ".
-                $response['access_token']."\r\n"]
-        ];
-        $data = \SimpleSAML\Utils\HTTP::fetch('https://graph.microsoft.com/v1.0/me', $opts);
-        $userdata = json_decode($data, true);
-
-        // this is the simplest case
-        if (!array_key_exists('@odata.context', $userdata) || array_key_exists('error', $userdata)) {
-            throw new \Exception(
-                'Unable to retrieve userdata from Microsoft Graph ['.$userdata['error']['code'].'] '.
-                $userdata['error']['message']
-            );
-        }
-        $attributes = [];
-        $attributes['windowslive_targetedID'] = [
-            'https://graph.microsoft.com!'.(!empty($userdata['id']) ? $userdata['id'] : 'unknown')
-        ];
-        foreach ($userdata as $key => $value) {
-            if (is_string($value)) {
-                $attributes['windowslive.'.$key] = [(string) $value];
-            }
-        }
-
-
-        \SimpleSAML\Logger::debug('LiveID Returned Attributes: '.implode(", ", array_keys($attributes)));
-
-        $state['Attributes'] = $attributes;
-    }
-}
diff --git a/modules/authwindowslive/www/linkback.php b/modules/authwindowslive/www/linkback.php
deleted file mode 100644
index 3800cd180b8440417cece31febaa91de31de20c3..0000000000000000000000000000000000000000
--- a/modules/authwindowslive/www/linkback.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-/**
- * Handle linkback() response from Windows Live ID.
- */
-
-if (!array_key_exists('state', $_REQUEST)) {
-    throw new \Exception('Lost OAuth Client State');
-}
-$state = \SimpleSAML\Auth\State::loadState(
-    $_REQUEST['state'],
-    \SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::STAGE_INIT
-);
-
-// http://msdn.microsoft.com/en-us/library/ff749771.aspx
-if (array_key_exists('code', $_REQUEST)) {
-    // good
-    $state['authwindowslive:verification_code'] = $_REQUEST['code'];
-
-    if (array_key_exists('exp', $_REQUEST)) {
-        $state['authwindowslive:exp'] = $_REQUEST['exp'];
-    }
-} else {
-    // In the OAuth WRAP service, error_reason = 'user_denied' means user chose
-    // not to login with LiveID. It isn't clear that this is still true in the
-    // newer API, but the parameter name has changed to error. It doesn't hurt
-    // to preserve support for this, so this is left in as a placeholder.
-    // redirect them to their original page so they can choose another auth mechanism
-    if ($_REQUEST['error'] === 'user_denied') {
-        $e = new \SimpleSAML\Error\UserAborted();
-        \SimpleSAML\Auth\State::throwException($state, $e);
-    }
-
-    // error
-    throw new \Exception('Authentication failed: ['.$_REQUEST['error'].'] '.$_REQUEST['error_description']);
-}
-
-// find authentication source
-assert(array_key_exists(\SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::AUTHID, $state));
-$sourceId = $state[\SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::AUTHID];
-
-/** @var \SimpleSAML\Module\authwindowslive\Auth\Source\LiveID|null $source */
-$source = \SimpleSAML\Auth\Source::getById($sourceId);
-if ($source === null) {
-    throw new \Exception('Could not find authentication source with id '.$sourceId);
-}
-
-$source->finalStep($state);
-
-\SimpleSAML\Auth\Source::completeAuth($state);