Add excluded Entra groups for the Microsoft sign-in
Some checks are pending
CI / PHP lint (7.4) (pull_request) Waiting to run
CI / PHP lint (8.0) (pull_request) Waiting to run
CI / PHP lint (8.1) (pull_request) Waiting to run
CI / PHP lint (8.2) (pull_request) Waiting to run
CI / PHP lint (8.3) (pull_request) Waiting to run
CI / PHP lint (8.4) (pull_request) Waiting to run
CI / WordPress Coding Standards (pull_request) Waiting to run
CI / WordPress.org Plugin Check (pull_request) Waiting to run

New "Excluded Entra groups" card on the Security tab. Members of these
groups (nested memberships count) can never sign in with Microsoft, even
if they are in an allowed group.

A hit in the ID token's groups claim refuses immediately. Otherwise the
plugin always asks Microsoft Graph (checkMemberGroups), because a groups
claim can be filtered in the app registration and cannot prove
non-membership. Graph errors refuse the sign-in (fail closed).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-23 16:43:10 +00:00
parent 5c9b19399a
commit 791f43a80b
12 changed files with 372 additions and 196 deletions

View file

@ -54,7 +54,7 @@ msgstr ""
msgid "Copied!"
msgstr ""
#: includes/class-m365-login-admin.php:233 includes/class-m365-login-admin.php:848 includes/class-m365-login-admin.php:1102 includes/class-m365-login-admin.php:1147
#: includes/class-m365-login-admin.php:233 includes/class-m365-login-admin.php:848 includes/class-m365-login-admin.php:1112 includes/class-m365-login-admin.php:1157
msgid "Copy"
msgstr ""
@ -912,136 +912,152 @@ msgid "Membership is read from the \"groups\" claim of the ID token when present
msgstr ""
#: includes/class-m365-login-admin.php:1085
msgid "Button-only mode"
msgid "Excluded Entra groups (optional)"
msgstr ""
#: includes/class-m365-login-admin.php:1086
msgid "Members of these groups can never sign in with Microsoft even if they are in an allowed group. Nested memberships count."
msgstr ""
#: includes/class-m365-login-admin.php:1088
msgid "No groups excluded."
msgstr ""
#: includes/class-m365-login-admin.php:1090
msgid "The plugin asks Microsoft Graph on every sign-in (application permission \"User.Read.All\" or \"Directory.Read.All\"), because a \"groups\" claim may be filtered and cannot prove that someone is not a member. If the check fails, the sign-in is refused. Password sign-in is not affected combine with button-only mode if needed."
msgstr ""
#: includes/class-m365-login-admin.php:1095
msgid "Button-only mode"
msgstr ""
#: includes/class-m365-login-admin.php:1096
msgid "Hides the username/password fields (on wp-login.php and in wp_login_form() forms) and refuses every interactive password sign-in on the site, including custom login forms. Application passwords, REST, XML-RPC and WP-CLI are not affected."
msgstr ""
#: includes/class-m365-login-admin.php:1091
#: includes/class-m365-login-admin.php:1101
msgid "Show only the Microsoft button on the login page"
msgstr ""
#: includes/class-m365-login-admin.php:1092
#: includes/class-m365-login-admin.php:1102
msgid "Becomes active once the connection is configured. Make sure your own account can sign in via Microsoft before enabling this."
msgstr ""
#: includes/class-m365-login-admin.php:1097
#: includes/class-m365-login-admin.php:1107
msgid "Fallback link (keep it secret)"
msgstr ""
#: includes/class-m365-login-admin.php:1098
#: includes/class-m365-login-admin.php:1108
msgid "Opening this link shows the password form again in that browser for 30 minutes and allows password sign-in there. Bookmark it somewhere safe it is your way back in if Microsoft sign-in ever breaks."
msgstr ""
#: includes/class-m365-login-admin.php:1106
#: includes/class-m365-login-admin.php:1116
msgid "Generate a new key when saving"
msgstr ""
#: includes/class-m365-login-admin.php:1109
#: includes/class-m365-login-admin.php:1119
msgid "A key is generated automatically the first time you save these settings."
msgstr ""
#. translators: %s: PHP constant
#: includes/class-m365-login-admin.php:1115
#: includes/class-m365-login-admin.php:1125
msgid "Emergency switch: add %s to wp-config.php to disable button-only mode entirely."
msgstr ""
#. translators: %s: PHP constant
#: includes/class-m365-login-admin.php:1124
#: includes/class-m365-login-admin.php:1134
msgid "What the plugin does to keep sign-ins safe"
msgstr ""
#: includes/class-m365-login-admin.php:1126
#: includes/class-m365-login-admin.php:1136
msgid "OpenID Connect authorization code flow with PKCE (S256) no tokens ever pass through the browser."
msgstr ""
#: includes/class-m365-login-admin.php:1127
#: includes/class-m365-login-admin.php:1137
msgid "Single-use state and nonce values bound to the browser via an HttpOnly cookie (CSRF and replay protection)."
msgstr ""
#: includes/class-m365-login-admin.php:1128
#: includes/class-m365-login-admin.php:1138
msgid "ID token signature verified against Microsofts published signing keys; issuer, audience, tenant, expiry and nonce are checked."
msgstr ""
#: includes/class-m365-login-admin.php:1129
#: includes/class-m365-login-admin.php:1139
msgid "Client secret encrypted at rest; sign-in never creates accounts or changes passwords."
msgstr ""
#: includes/class-m365-login-admin.php:1137
#: includes/class-m365-login-admin.php:1147
msgid "Save changes"
msgstr ""
#: includes/class-m365-login-admin.php:1143
#: includes/class-m365-login-admin.php:1153
msgid "Redirect URI"
msgstr ""
#: includes/class-m365-login-admin.php:1144
#: includes/class-m365-login-admin.php:1154
msgid "Register this URI in your app registration under Authentication → Web → Redirect URIs:"
msgstr ""
#: includes/class-m365-login-admin.php:1150
#: includes/class-m365-login-admin.php:1160
msgid "Plain permalinks are active, so the callback uses a query string. If you enable pretty permalinks later, the redirect URI changes and must be updated in Entra ID."
msgstr ""
#: includes/class-m365-login-admin.php:1153
#: includes/class-m365-login-admin.php:1163
msgid "Your site does not use HTTPS. Microsoft only accepts http:// redirect URIs for localhost; production sites must use HTTPS."
msgstr ""
#: includes/class-m365-login-admin.php:1158
#: includes/class-m365-login-admin.php:1168
msgid "Setup guide: app registration"
msgstr ""
#: includes/class-m365-login-admin.php:1160
#: includes/class-m365-login-admin.php:1170
msgid "Open entra.microsoft.com → Identity → Applications → App registrations → New registration."
msgstr ""
#: includes/class-m365-login-admin.php:1161
#: includes/class-m365-login-admin.php:1171
msgid "Name: e.g. \"WordPress login\". Supported account types: \"Accounts in this organizational directory only\" (single tenant)."
msgstr ""
#: includes/class-m365-login-admin.php:1162
#: includes/class-m365-login-admin.php:1172
msgid "Redirect URI: choose the platform Web and paste the URI shown above. Then click Register."
msgstr ""
#: includes/class-m365-login-admin.php:1163
#: includes/class-m365-login-admin.php:1173
msgid "On the Overview page copy the Application (client) ID and the Directory (tenant) ID into the Connection tab."
msgstr ""
#: includes/class-m365-login-admin.php:1164
#: includes/class-m365-login-admin.php:1174
msgid "Authentication: leave \"ID tokens\" unchecked (the plugin uses the authorization code flow) and \"Allow public client flows\" on No."
msgstr ""
#: includes/class-m365-login-admin.php:1165
#: includes/class-m365-login-admin.php:1175
msgid "Token configuration → Add optional claim → ID → tick \"email\" → Add. Confirm the API permission prompt."
msgstr ""
#: includes/class-m365-login-admin.php:1166
#: includes/class-m365-login-admin.php:1176
msgid "Pick the authentication method on the Connection tab and follow its step-by-step guide (client secret or certificate)."
msgstr ""
#: includes/class-m365-login-admin.php:1167
#: includes/class-m365-login-admin.php:1177
msgid "Optional: restrict who may use the app under Enterprise applications → your app → Properties → \"Assignment required\" = Yes, then assign users/groups."
msgstr ""
#: includes/class-m365-login-admin.php:1169
#: includes/class-m365-login-admin.php:1179
msgid "Required API permission: openid, profile, email (delegated) granted by default."
msgstr ""
#: includes/class-m365-login-admin.php:1170
#: includes/class-m365-login-admin.php:1180
msgid "Optional, for group restrictions and the user sync: application permissions GroupMember.Read.All and User.Read.All (Microsoft Graph) with admin consent."
msgstr ""
#: includes/class-m365-login-admin.php:1174
#: includes/class-m365-login-admin.php:1184
msgid "Shortcode"
msgstr ""
#: includes/class-m365-login-admin.php:1175
#: includes/class-m365-login-admin.php:1185
msgid "Place the button on a custom login page:"
msgstr ""
#: includes/class-m365-login-admin.php:1177
#: includes/class-m365-login-admin.php:1187
msgid "More options on the Button tab under \"Custom login page\"."
msgstr ""
@ -1049,75 +1065,79 @@ msgstr ""
msgid "Password sign-in is disabled on this site. Please use the Microsoft button."
msgstr ""
#: includes/class-m365-login-auth.php:827
#: includes/class-m365-login-auth.php:906
msgid "Password sign-in is temporarily enabled for this browser (30 minutes)."
msgstr ""
#: includes/class-m365-login-auth.php:848 includes/class-m365-login-graph.php:63
#: includes/class-m365-login-auth.php:927 includes/class-m365-login-graph.php:63
msgid "Microsoft login is not configured yet."
msgstr ""
#: includes/class-m365-login-auth.php:849
#: includes/class-m365-login-auth.php:928
msgid "The login request expired or was invalid. Please try again."
msgstr ""
#: includes/class-m365-login-auth.php:850
#: includes/class-m365-login-auth.php:929
msgid "Microsoft sign-in was cancelled."
msgstr ""
#: includes/class-m365-login-auth.php:851
#: includes/class-m365-login-auth.php:930
msgid "Microsoft returned an error. Please try again."
msgstr ""
#: includes/class-m365-login-auth.php:852
#: includes/class-m365-login-auth.php:931
msgid "Could not complete the sign-in with Microsoft. Please try again or contact an administrator."
msgstr ""
#: includes/class-m365-login-auth.php:853
#: includes/class-m365-login-auth.php:932
msgid "The Microsoft sign-in could not be verified."
msgstr ""
#: includes/class-m365-login-auth.php:854
#: includes/class-m365-login-auth.php:933
msgid "Your Microsoft account did not provide an e-mail address."
msgstr ""
#: includes/class-m365-login-auth.php:855
#: includes/class-m365-login-auth.php:934
msgid "Your e-mail domain is not allowed to sign in here."
msgstr ""
#: includes/class-m365-login-auth.php:856
#: includes/class-m365-login-auth.php:935
msgid "No WordPress account exists for your Microsoft e-mail address."
msgstr ""
#: includes/class-m365-login-auth.php:857
#: includes/class-m365-login-auth.php:936
msgid "This WordPress account is linked to a different Microsoft account. Please contact an administrator."
msgstr ""
#: includes/class-m365-login-auth.php:858
#: includes/class-m365-login-auth.php:937
msgid "You are not allowed to sign in with this account."
msgstr ""
#: includes/class-m365-login-auth.php:859
#: includes/class-m365-login-auth.php:938
msgid "Your Microsoft account is not a member of a group that is allowed to sign in here."
msgstr ""
#: includes/class-m365-login-auth.php:860
#: includes/class-m365-login-auth.php:939
msgid "Your group membership could not be verified. Please contact an administrator."
msgstr ""
#: includes/class-m365-login-auth.php:861
#: includes/class-m365-login-auth.php:940
msgid "Your Microsoft account is a member of a group that is not allowed to sign in here."
msgstr ""
#: includes/class-m365-login-auth.php:941
msgid "The fallback key is not valid."
msgstr ""
#: includes/class-m365-login-auth.php:862
#: includes/class-m365-login-auth.php:942
msgid "Too many attempts. Please wait 15 minutes."
msgstr ""
#: includes/class-m365-login-auth.php:863
#: includes/class-m365-login-auth.php:943
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
msgstr ""
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1520
#: includes/class-m365-login-auth.php:944 includes/class-m365-login-sync.php:1520
msgid "This account has been deactivated."
msgstr ""
@ -1185,51 +1205,51 @@ msgstr ""
msgid "Microsoft 365 group"
msgstr ""
#: includes/class-m365-login-settings.php:54
#: includes/class-m365-login-settings.php:55
msgid "Sign in with Microsoft"
msgstr ""
#: includes/class-m365-login-settings.php:63
#: includes/class-m365-login-settings.php:64
msgid "or"
msgstr ""
#: includes/class-m365-login-settings.php:225 includes/class-m365-login-settings.php:530
#: includes/class-m365-login-settings.php:226 includes/class-m365-login-settings.php:540
msgid "The private key could not be encrypted. Is the OpenSSL extension available?"
msgstr ""
#: includes/class-m365-login-settings.php:476
#: includes/class-m365-login-settings.php:486
msgid "The tenant ID must be a GUID (e.g. 1a2b3c4d-…) or one of \"organizations\", \"common\", \"consumers\"."
msgstr ""
#: includes/class-m365-login-settings.php:484
#: includes/class-m365-login-settings.php:494
msgid "The application (client) ID must be a GUID."
msgstr ""
#: includes/class-m365-login-settings.php:496
#: includes/class-m365-login-settings.php:506
msgid "The client secret contains invalid characters."
msgstr ""
#: includes/class-m365-login-settings.php:500
#: includes/class-m365-login-settings.php:510
msgid "The client secret could not be encrypted. Is the OpenSSL extension available?"
msgstr ""
#: includes/class-m365-login-settings.php:520
#: includes/class-m365-login-settings.php:530
msgid "Please paste both the private key and the certificate."
msgstr ""
#: includes/class-m365-login-settings.php:522
#: includes/class-m365-login-settings.php:532
msgid "The pasted key or certificate is too large."
msgstr ""
#: includes/class-m365-login-settings.php:539
#: includes/class-m365-login-settings.php:549
msgid "Certificate authentication is selected but no certificate is stored yet. Generate one or paste your own; the Microsoft button stays hidden until then."
msgstr ""
#: includes/class-m365-login-settings.php:571
#: includes/class-m365-login-settings.php:582
msgid "The custom login page must be a URL on this site."
msgstr ""
#: includes/class-m365-login-settings.php:678
#: includes/class-m365-login-settings.php:689
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
msgstr ""