Security, Queries, and Specialized Extensions |
![]() |
Security first authenticates a repository user and then authorizes that identity's operations. Query handling is a separate extension domain with a language/factory contract. Use these supported seams instead of general handlers for authentication, authorization, or a custom query language. Deployment credentials, password files, TLS, and directory-server configuration remain Operator's Guide topics.
| 1 | Repository Protection | ||
| 2 | Permission Cache SPI | ||
| 3 | Authentication Example | ||
| 4 | Query Handlers | ||
| 5 | Extension Boundaries | ||
IRepositoryProtector protects a repository by combining a UserAuthenticator, authorization
strategy, revision authorizers, and commit handlers. Authentication answers “which repository user presented
these credentials?” Returning null rejects session opening; a returned identity becomes the user ID in the
server session. Authorization answers “what may this identity do?” and is evaluated on repository reads and
commits; authentication alone grants no access. Delegate credential verification to application policy rather
than embedding password storage in this integration.
The authenticator establishes repository user identity;
for the surrounding repository configuration. A custom
protector product must be registered in its product group; applications do not implement
IRepositoryProtector directly.
The optional org.eclipse.emf.cdo.server.security module provides the PermissionCache and
PermissionCacheFactory SPIs for applications that need an alternative resource-permission cache. Register
a PermissionCacheFactory product in its managed-container product group, then select its type and optional description with
repository properties security.permissionCache.type and
security.permissionCache.description. The built-in factory type is default; its description can
set creator capacity (for example |capacity=50000). The optional repository property
security.permissionCache.default.capacity also supplies that capacity when no description suffix is
present. Invalid or nonpositive capacity fails factory creation and therefore repository startup. The security extension also accepts one permissionCache child under
securityManager; omitting its type selects the default cache. The default implementation has a configurable
capacity, whose documented default is 100,000 entries. The internal security-manager setter is not an application
configuration API.
Authorization evaluates resource, class, object, and global policy. The cache stores only a resource node's
permission and the baseline inherited by ordinary contained objects; other policy checks remain separate. The
security manager caches a resource baseline in two separate slots for each resource-node ID: permission on the
resource node itself, and the baseline inherited by ordinary objects in that resource. The built-in resource
permissions and resource filters can contribute to this baseline. Composed filters are cacheable only when their
operands are cacheable; arbitrary class and package filters are not automatically treated as resource-stable.
Custom Permission and PermissionFilter implementations are dynamic by default. The implementation
has protected resource-cache classification hooks, but they are not a public application extension point; do not
subclass an internal security-manager implementation to reach them. Keep custom policy dynamic, especially when
it depends on request-local state, transactions, object contents, or AuthorizationContext.
Cached authorization applies only to reads at the current branch head. Historical reads and commit authorization
remain uncached. Cache generations are isolated by repository, user, and branch, and relevant realm or
resource-tree changes invalidate affected generations. A custom implementation must ensure that writes racing with
invalidation cannot populate the replacement generation. This also applies independently to secondary repositories.
A dynamic permission that depends on AuthorizationContext is evaluated outside the cached resource
baseline on each authorization.
A custom PermissionCache.Creator must return a fresh logical generation for each repository/user/branch
scope and keep late writes to an obsolete generation from becoming visible through its replacement. The cache
implementation must support concurrent authorization access. The built-in cache's 100,000-entry capacity is shared
by its creator's backing store; it is not a separate quota for every user or branch. Invalid capacity
configuration prevents creator creation and therefore repository startup.
An authenticator must delegate credential validation to application-owned policy and return null when the
policy rejects the credentials. This example shows the integration seam without embedding credentials or choosing
a password-storage scheme.
The client creates a query with a language identifier, query string, and named parameters. The server provider
selects a factory by language; that factory creates an
Repository factories, query handler factories, repository-protector elements, DB adapters, and mapping
strategies are container/factory extension mechanisms. They serve different responsibilities and should not be
confused with application extensions. Use a supported factory SPI only when the application must supply that
product; otherwise configure an existing product.
IRepositoryProtector.AuthorizationStrategy combines permissions; a
IRepositoryProtector.RevisionAuthorizer decides revision permissions; and a
IRepositoryProtector.CommitHandler runs before security checking and after a successful protected commit.
In server XML, the repository's IRepositoryProtector.PRODUCT_GROUP; its child elements select authenticator, authorization-strategy,
revision-authorizer, and commit-handler products. This core repository-configurator extension is distinct from
the optional security module. When org.eclipse.emf.cdo.server.security is installed, its application
extension recognizes a separate IPermissionManager is the legacy permission-management API used by the security model. The optional
org.eclipse.emf.cdo.server.security module supplies its own ISecurityManager; use its public API
when that module is intentionally part of an application, without coupling to its internal realm implementation.
2 Permission Cache SPI
3 Authentication Example
4 Query Handlers
IQueryHandler, which receives
query info and an IQueryContext carrying server view/session and branch-point context.
Results flow through IQueryContext.addResult(Object); the handler stops when that method returns
false or the context is cancelled. Register handler factories in
QueryHandlerFactory.PRODUCT_GROUP; the factory type is the query language, so container configuration can
select the handler. Implement IQueryHandler.PotentiallySlow when a handler can identify slow query forms.
OCL is a supplied optional handler integration; this guide does not teach the OCL language itself. A custom
language becomes reachable only after its factory is registered in the server container; the client's language
string must match the factory type.
A useful custom handler often adapts an application-owned, repository-aware index: parse a query string or
parameter, find matching persistent IDs, and pass them to the context. The index must honor the query's branch and
time semantics; a global current-state index is not correct for historical views. The handler must check
cancellation during long scans and stop when IQueryContext.addResult(Object) returns false.
5 Extension Boundaries
All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html