Security Provider Extension
This page explains two important security abstractions in geelato-security:
UserProviderOrgProvider
It covers why they exist, how the default implementation works, and how a host application can replace the default security data source.
What Problem They Solve
The runtime security chain should not hard-code where user and organization data comes from.
So the framework exposes two provider boundaries:
UserProviderOrgProvider
This lets consumers depend on a stable read interface while the actual source can come from:
- JDBC snapshots
- external IAM
- enterprise WeChat
- an organization center
- cache infrastructure
- an aggregation service
What UserProvider Does
UserProvider exposes user-side read access such as:
getUser(String userId)getUserById(String userId)getUserByExtendKey(String extendKey, String type)getUserRoles(String userId)getUserOrgs(String userId)refresh()
It also provides helper defaults such as:
getUserName(...)containsUser(...)normalizeType(...)
The type normalization already aligns common identity names such as:
loginNameweixinUnionIdweixinWorkUserId
What OrgProvider Does
OrgProvider exposes organization-side read access such as:
getOrg(String orgId)getOrgName(String orgId)getDeptId(String orgId)getCompanyId(String orgId)getBuId(String orgId)refresh()
So it is not just a simple organization lookup interface. It is also a relationship-resolution entry for department and company/BU derivation.
Where They Are Used
They are key dependencies in the runtime security chain, including:
DefaultSecurityInterceptorInterceptorConfigurationSecurityDataRefreshCoordinatorUser.setupOrgInfo(...)
So they are not optional helpers. They are the data-provider boundary of runtime security.
How the Default Wiring Works
The default wiring is created in:
SecurityProviderConfiguration
through:
@ConditionalOnMissingBean(OrgProvider.class)@ConditionalOnMissingBean(UserProvider.class)
The default beans are:
DefaultOrgProviderDefaultUserProvider
That means they are intentionally designed as replaceable extension points.
Default Model
The current default model is:
- loaders build snapshots
- providers expose read access over those snapshots
- upper security logic depends only on providers
The default loaders are:
JdbcOrgSnapshotLoaderJdbcUserSnapshotLoader
The default providers are:
DefaultOrgProviderDefaultUserProvider
and refresh is coordinated by:
SecurityDataRefreshCoordinator
How To Extend
Option 1: Replace the Provider Directly
If you already have a complete user or organization access model, provide your own:
OrgProviderUserProvider
Because the defaults are protected by @ConditionalOnMissingBean, your beans will replace them naturally.
Option 2: Keep the Provider, Replace the Loader
If you like the default snapshot-based provider model but want a different source, replace:
OrgSnapshotLoaderUserSnapshotLoader
This lets you keep:
DefaultOrgProviderDefaultUserProviderSecurityDataRefreshCoordinator
while moving the actual data source to another backend.
Option 3: Replace the User Org Enricher
For user organization enrichment, the framework also keeps:
UserOrgInfoEnricher
If your user snapshot is incomplete or organization binding needs custom derivation, replacing this layer can be enough.
Runtime Considerations
When replacing providers or loaders, keep these behaviors stable:
refresh()really reloads the latest snapshot- org resolution still supports department and company/BU derivation
getUserByExtendKey(...)still supports external identity mapping when required
This is especially important because UserProvider.getUserByExtendKey(...) directly supports non-standard auth entries such as:
WeixinUnionIdWeixinWorkUserId
Recommended Strategy
The usual order is:
- decide whether you need to change the source only or the whole provider behavior
- if only the source changes, replace the snapshot loader first
- if the snapshot model itself does not fit, replace the provider directly
- keep refresh and identity mapping semantics stable
Summary
UserProvider and OrgProvider are two of the most important security extension abstractions in the current framework:
UserProviderhandles user access, role lookup, organization binding, and extended identity mappingOrgProviderhandles organization lookup and organization relationship resolution- the default model is
Loader -> Snapshot -> Provider - the default beans are protected by
@ConditionalOnMissingBean, so host applications can override them cleanly
This makes them suitable as:
- unified identity-source integration points
- organization-center integration points
- extension boundaries for external IAM, enterprise WeChat, or custom account systems