diff --git a/bitwarden_license/src/Sso/Controllers/AccountController.cs b/bitwarden_license/src/Sso/Controllers/AccountController.cs
index 00657a4e7f..5776912bd3 100644
--- a/bitwarden_license/src/Sso/Controllers/AccountController.cs
+++ b/bitwarden_license/src/Sso/Controllers/AccountController.cs
@@ -255,9 +255,12 @@ public class AccountController : Controller
_logger.LogDebug("External claims: {@claims}", externalClaims);
// Lookup our user and external provider info
+ // Note: the user will only exist if the user has already been provisioned and exists in the User table and the SSO user table.
var (user, provider, providerUserId, claims, ssoConfigData) = await FindUserFromExternalProviderAsync(result);
if (user == null)
{
+ // User does not exist in SSO User table. They could have an existing BW account in the User table.
+
// This might be where you might initiate a custom workflow for user registration
// in this sample we don't show how that would be done, as our sample implementation
// simply auto-provisions new external user
@@ -268,6 +271,8 @@ public class AccountController : Controller
if (user != null)
{
+ // User was JIT provisioned (this could be an existing user or a new user)
+
// This allows us to collect any additional claims or properties
// for the specific protocols used and store them in the local auth cookie.
// this is typically used to store data needed for signout from those protocols.
@@ -487,12 +492,8 @@ public class AccountController : Controller
throw new Exception(_i18nService.T("UserAlreadyExistsInviteProcess"));
}
- if (orgUser.Status == OrganizationUserStatusType.Invited)
- {
- // Org User is invited - they must manually accept the invite via email and authenticate with MP
- // This allows us to enroll them in MP reset if required
- throw new Exception(_i18nService.T("AcceptInviteBeforeUsingSSO", organization.DisplayName()));
- }
+ EnsureOrgUserStatusAllowed(orgUser.Status, organization.DisplayName(),
+ allowedStatuses: [OrganizationUserStatusType.Accepted, OrganizationUserStatusType.Confirmed]);
// Accepted or Confirmed - create SSO link and return;
await CreateSsoUserRecord(providerUserId, existingUser.Id, orgId, orgUser);
@@ -587,6 +588,36 @@ public class AccountController : Controller
return user;
}
+ private void EnsureOrgUserStatusAllowed(
+ OrganizationUserStatusType status,
+ string organizationDisplayName,
+ params OrganizationUserStatusType[] allowedStatuses)
+ {
+ // if this status is one of the allowed ones, just return
+ if (allowedStatuses.Contains(status))
+ {
+ return;
+ }
+
+ // otherwise throw the appropriate exception
+ switch (status)
+ {
+ case OrganizationUserStatusType.Invited:
+ // Org User is invited – must accept via email first
+ throw new Exception(
+ _i18nService.T("AcceptInviteBeforeUsingSSO", organizationDisplayName));
+ case OrganizationUserStatusType.Revoked:
+ // Revoked users may not be (auto)‑provisioned
+ throw new Exception(
+ _i18nService.T("OrganizationUserAccessRevoked", organizationDisplayName));
+ default:
+ // anything else is “unknown”
+ throw new Exception(
+ _i18nService.T("OrganizationUserUnknownStatus", organizationDisplayName));
+ }
+ }
+
+
private IActionResult InvalidJson(string errorMessageKey, Exception ex = null)
{
Response.StatusCode = ex == null ? 400 : 500;
diff --git a/src/Core/Resources/SharedResources.en.resx b/src/Core/Resources/SharedResources.en.resx
index 90a791222f..97cac5a610 100644
--- a/src/Core/Resources/SharedResources.en.resx
+++ b/src/Core/Resources/SharedResources.en.resx
@@ -532,6 +532,12 @@
To accept your invite to {0}, you must first log in using your master password. Once your invite has been accepted, you will be able to log in using SSO.
+
+ Your access to organization {0} has been revoked. Please contact your administrator for assistance.
+
+
+ Your access to organization {0} is in an unknown state. Please contact your administrator for assistance.
+
You were removed from the organization managing single sign-on for your account. Contact the organization administrator for help regaining access to your account.