]> BookStack Code Mirror - bookstack/commitdiff
Reviewed SAML SLS changes for ADFS, #2902
authorDan Brown <redacted>
Sat, 23 Oct 2021 16:26:01 +0000 (17:26 +0100)
committerDan Brown <redacted>
Sat, 23 Oct 2021 16:26:01 +0000 (17:26 +0100)
- Migrated env usages to config.
- Removed potentially unneeded config options or auto-set signed options
  based upon provision of certificate.
- Aligned SP certificate env option naming with similar IDP option.

Tested via AFDS on windows server 2019. To test on other providers.

.env.example.complete
app/Auth/Access/Saml2Service.php
app/Config/saml2.php
app/Http/Controllers/Auth/Saml2Controller.php

index a29afaafd014f600cd90784f39d04b1b76841670..683db703c6b59e78a8ad941fc7078dad9adf9f23 100644 (file)
@@ -232,11 +232,8 @@ SAML2_ONELOGIN_OVERRIDES=null
 SAML2_DUMP_USER_DETAILS=false
 SAML2_AUTOLOAD_METADATA=false
 SAML2_IDP_AUTHNCONTEXT=true
-SAML2_SP_CERTIFICATE=null
-SAML2_SP_PRIVATEKEY=null
-SAML2_SP_NAME_ID_Format=null
-SAML2_SP_NAME_ID_SP_NAME_QUALIFIER=null
-SAML2_RETRIEVE_PARAMETERS_FROM_SERVER=false
+SAML2_SP_x509=null
+SAML2_SP_x509_KEY=null
 
 # SAML group sync configuration
 # Refer to https://www.bookstackapp.com/docs/admin/saml2-auth/
index 58f999709e881fab60142017a4d1e9cef56b572c..ad889faf7c158767f74f8e20fcbbfce8268e0b70 100644 (file)
@@ -9,6 +9,7 @@ use BookStack\Exceptions\StoppedAuthenticationException;
 use BookStack\Exceptions\UserRegistrationException;
 use Exception;
 use OneLogin\Saml2\Auth;
+use OneLogin\Saml2\Constants;
 use OneLogin\Saml2\Error;
 use OneLogin\Saml2\IdPMetadataParser;
 use OneLogin\Saml2\ValidationError;
@@ -59,17 +60,20 @@ class Saml2Service
      *
      * @throws Error
      */
-    public function logout(): array
+    public function logout(User $user): array
     {
         $toolKit = $this->getToolkit();
         $returnRoute = url('/');
 
         try {
-            $email = auth()->user()['email'];
-            $nameIdFormat = env('SAML2_SP_NAME_ID_Format', null);
-            $nameIdSPNameQualifier = env('SAML2_SP_NAME_ID_SP_NAME_QUALIFIER', null);
-
-            $url = $toolKit->logout($returnRoute, [], $email, null, true, $nameIdFormat, null, $nameIdSPNameQualifier);
+            $url = $toolKit->logout(
+                $returnRoute,
+                [],
+                $user->email,
+                null,
+                true,
+                Constants::NAMEID_EMAIL_ADDRESS
+            );
             $id = $toolKit->getLastRequestID();
         } catch (Error $error) {
             if ($error->getCode() !== Error::SAML_SINGLE_LOGOUT_NOT_SUPPORTED) {
@@ -128,10 +132,13 @@ class Saml2Service
     public function processSlsResponse(?string $requestId): ?string
     {
         $toolkit = $this->getToolkit();
-        $retrieveParametersFromServer = env('SAML2_RETRIEVE_PARAMETERS_FROM_SERVER', false);
-
-        $redirect = $toolkit->processSLO(true, $requestId, $retrieveParametersFromServer, null, true);
 
+        // The $retrieveParametersFromServer in the call below will mean the library will take the query
+        // parameters, used for the response signing, from the raw $_SERVER['QUERY_STRING']
+        // value so that the exact encoding format is matched when checking the signature.
+        // This is primarily due to ADFS encoding query params with lowercase percent encoding while
+        // PHP (And most other sensible providers) standardise on uppercase.
+        $redirect = $toolkit->processSLO(true, $requestId, true, null, true);
         $errors = $toolkit->getErrors();
 
         if (!empty($errors)) {
index 3c4319100a1d67f8d841e1b5e8625e734d923776..44d06c5b2e60c6bb47af0a6970e3b3566dd1e927 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 $SAML2_IDP_AUTHNCONTEXT = env('SAML2_IDP_AUTHNCONTEXT', true);
+$SAML2_SP_x509 = env('SAML2_SP_x509', false);
 
 return [
 
@@ -78,10 +79,11 @@ return [
             // represent the requested subject.
             // Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported
             'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
+
             // Usually x509cert and privateKey of the SP are provided by files placed at
             // the certs folder. But we can also provide them with the following parameters
-            'x509cert'   => env('SAML2_SP_CERTIFICATE', ''),
-            'privateKey' => env('SAML2_SP_PRIVATEKEY', ''),
+            'x509cert'   => $SAML2_SP_x509 ?: '',
+            'privateKey' => env('SAML2_SP_x509_KEY', ''),
         ],
         // Identity Provider Data that we want connect with our SP
         'idp' => [
@@ -147,9 +149,11 @@ return [
             // Multiple forced values can be passed via a space separated array, For example:
             // SAML2_IDP_AUTHNCONTEXT="urn:federation:authentication:windows urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
             'requestedAuthnContext' => is_string($SAML2_IDP_AUTHNCONTEXT) ? explode(' ', $SAML2_IDP_AUTHNCONTEXT) : $SAML2_IDP_AUTHNCONTEXT,
-            'logoutRequestSigned'   => env('SAML2_LOGOUT_REQUEST_SIGNED', false),
-            'logoutResponseSigned'  => env('SAML2_LOGOUT_RESPONSE_SIGNED', false),
-            'lowercaseUrlencoding'  => env('SAML2_LOWERCASE_URLENCODING', false),
+            // Sign requests and responses if a certificate is in use
+            'logoutRequestSigned'   => (bool) $SAML2_SP_x509,
+            'logoutResponseSigned'  => (bool) $SAML2_SP_x509,
+            'authnRequestsSigned'   => (bool) $SAML2_SP_x509,
+            'lowercaseUrlencoding'  => false,
         ],
     ],
 
index 871abf59f9114f222c73301423d75c279d815009..bd3b25da770ab113e04c2298b6d0b4d3f7b6f907 100644 (file)
@@ -37,7 +37,7 @@ class Saml2Controller extends Controller
      */
     public function logout()
     {
-        $logoutDetails = $this->samlService->logout();
+        $logoutDetails = $this->samlService->logout(auth()->user());
 
         if ($logoutDetails['id']) {
             session()->flash('saml2_logout_request_id', $logoutDetails['id']);