diff --git a/news/1304.feature b/news/1304.feature
new file mode 100644
index 0000000000..62ab897692
--- /dev/null
+++ b/news/1304.feature
@@ -0,0 +1,2 @@
+Logging in to or out of the Zope root ZMI or the API does the same in the other.
+[rpatterson]
diff --git a/setup.py b/setup.py
index 13e5231239..3f76af8634 100644
--- a/setup.py
+++ b/setup.py
@@ -84,6 +84,7 @@ def read(filename):
"plone.schema >= 1.2.1", # new/fixed json field
"PyJWT",
"pytz",
+ "collective.monkeypatcher",
],
extras_require={"test": TEST_REQUIRES},
entry_points="""
diff --git a/src/plone/restapi/configure.zcml b/src/plone/restapi/configure.zcml
index 5fcfb0e47a..6020bd9cb9 100644
--- a/src/plone/restapi/configure.zcml
+++ b/src/plone/restapi/configure.zcml
@@ -91,6 +91,7 @@
+
diff --git a/src/plone/restapi/pas/__init__.py b/src/plone/restapi/pas/__init__.py
index e69de29bb2..6fd571e370 100644
--- a/src/plone/restapi/pas/__init__.py
+++ b/src/plone/restapi/pas/__init__.py
@@ -0,0 +1,22 @@
+"""
+A JWT token authentication plugin for PluggableAuthService.
+"""
+
+from App import Management
+from Products import PluggableAuthService # noqa, Ensure PAS patch in place
+
+
+_orig_manage_zmi_logout = Management.Navigation.manage_zmi_logout
+
+
+# BBB: Maybe remove depending on the outcome of the PAS issue:
+# https://github.com/zopefoundation/Products.PluggableAuthService/issues/107#issue-1090137890
+def manage_zmi_logout(self, REQUEST, RESPONSE):
+ """
+ Logout the current ZMI user without re-challenging for login credentials.
+ """
+ _orig_manage_zmi_logout(self, REQUEST, RESPONSE)
+
+ # Undo the HTTP `Authorization: Basic ...` assumptions
+ del RESPONSE.headers["WWW-Authenticate"]
+ RESPONSE.setStatus(200)
diff --git a/src/plone/restapi/pas/configure.zcml b/src/plone/restapi/pas/configure.zcml
new file mode 100644
index 0000000000..99be49d239
--- /dev/null
+++ b/src/plone/restapi/pas/configure.zcml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/src/plone/restapi/tests/test_functional_auth.py b/src/plone/restapi/tests/test_functional_auth.py
index fb83c1846d..bd1aa7a502 100644
--- a/src/plone/restapi/tests/test_functional_auth.py
+++ b/src/plone/restapi/tests/test_functional_auth.py
@@ -378,10 +378,23 @@ def test_root_zmi_logout_expires_api_token(self):
login_form.controls[-1].click()
# Click the ZMI logout link
- browser.raiseHttpErrors = False
logout_link = browser.getLink(url="manage_zmi_logout")
logout_link.click()
- browser.raiseHttpErrors = True
+ self.assertEqual(
+ browser.headers["Status"].lower(),
+ "200 ok",
+ "Wrong Zope root `/acl_users` logout response status",
+ )
+ self.assertEqual(
+ browser.url,
+ self.app.absolute_url() + "/manage_zmi_logout",
+ "Wrong Zope root `/acl_users` logout response URL",
+ )
+ self.assertIn(
+ "You have been logged out",
+ browser.contents,
+ "Zope root `/acl_users` logout response missing confirmation message",
+ )
self.assertNotIn(
"__ac",
browser.cookies,