Authorization API

Last modified by Admin on 2026/05/27 13:32

cogControls permissions to all the wiki elements
TypeJAR
Category
Developed by

XWiki Development Team

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Standard

Success

Installable with the Extension Manager

Description

This module handles user authentication, access authorization and contextual security. Current status:

  • The Authorization API is implemented by providing a bridge to the (old) RightService APIs (see $xwiki.hasAccessLevel()). This bridge has been used by default since release 5.0M2. This module has been available since release 4.0M1, but it should be considered stable only since 5.0 release.
  • The Authentication API has not yet been implemented (the old core code is currently used and documented). However, some authentication-related APIs have been introduced (see below).

Security Authorization API

For ensuring efficiency, this module uses caching techniques to store both access rules, and resulting access decisions made by the authorization settler. Checking multiple times access to the same object (or object of the same hierarchy not having special access) for the same user requires only very fast cache lookups. The bridged version of the old com.xpn.xwiki.user.impl.xwiki.XWikiRightServiceImpl is therefore called org.xwiki.security.authorization.internal.XWikiCachingRightService. It should only be used when the new API does not fit your needs.

Warning

Since the contextual aspect of the module is not yet available, this module does not provide any contextual answers and only provides access answers based on static (during a request) access rules. (i.e. DropPermission is only supported by the bridged XWikiCachingRightService.)

General API interface

Provided by Role org.xwiki.security.authorization.AuthorizationManager:

    /**
     * Check if the user identified by {@code userReference} has the access identified by {@code right} on the
     * entity identified by {@code entityReference}.
     * This function should be used at security checkpoint.
     */
    void checkAccess(Right right, DocumentReference userReference, EntityReference entityReference)
        throws AccessDeniedException;

    /**
     * Verifies if the user identified by {@code userReference} has the access identified by {@code right} on the
     * entity identified by {@code entityReference}.
     * This function should be used for interface matters, use {@link #checkAccess} at security checkpoints.
     */
    boolean hasAccess(Right right, DocumentReference userReference, EntityReference entityReference);

    /**
     * Register a new custom {@link Right}.
     */
    Right register(RightDescription rightDescription) throws UnableToRegisterRightException;

    /**
     * Register a new custom {@link Right} and add it as an implied right to the given set of rights.
     *
     * @param rightDescription the full description of the new {@link Right}
     * @param impliedByRights the rights that should imply the new right.
     * @return the created {@link Right}
     * @throws UnableToRegisterRightException if an error prevent creation of the new right. Registering exactly
     * the same right does not cause an exception and return the existing right.
     * @since 12.6
     */
    Right register(RightDescription rightDescription, Set<Right> impliedByRights) throws UnableToRegisterRightException;

    /**
     * Unregister the given custom {@link Right}.
     *
     * @param right the custom right to unregister.
     * @throws AuthorizationException if the right is not custom.
     * @since 13.5RC1
     */
    void unregister(Right right) throws AuthorizationException;

Contextual API interface (since 6.1RC1)

Provided by Role org.xwiki.security.authorization.ContextualAuthorizationManager:

    /**
     * Check if access identified by {@code right} on the current entity is allowed in the current context.
     * This function should be used at security checkpoint.
     *
     * @param right the right needed for execution of the action
     * @throws AccessDeniedException if the action should be denied, which may also happen when an error occurs
     */
    void checkAccess(Right right) throws AccessDeniedException;

    /**
     * Verifies if access identified by {@code right} on the current entity would be allowed in the current context.
     * This function should be used for interface matters, use {@link #checkAccess} at security checkpoints.
     *
     * @param right the right to check .
     * @return {@code true} if the user has the specified right on the entity, {@code false} otherwise
     */
    boolean hasAccess(Right right);

    /**
     * Check if access identified by {@code right} on the given entity is allowed in the current context.
     * This function should be used at security checkpoint.
     *
     * @param right the right needed for execution of the action
     * @param entityReference the entity on which to check the right
     * @throws AccessDeniedException if the action should be denied, which may also happen when an error occurs
     */
    void checkAccess(Right right, EntityReference entityReference) throws AccessDeniedException;

    /**
     * Verifies if access identified by {@code right} on the given entity would be allowed in the current context.
     * This function should be used for interface matters, use {@link #checkAccess} at security checkpoints.
     *
     * @param right the right to check .
     * @param entityReference the entity on which to check the right
     * @return {@code true} if the user has the specified right on the entity, {@code false} otherwise
     */
    boolean hasAccess(Right right, EntityReference entityReference);

The context includes information like the authenticated user, the current macro being executed, the rendering context restriction, the dropping of rights by macro, etc...
If you doubt which API to use, you should use the contextual one unless you check rights out of context.

XWiki 16.10.0+

Document authorization manager

The DocumentAuthorizationManager needs to be used when rights of a document author need to be checked, for example, to verify if a certain XObject that requires wiki admin rights actually has wiki admin rights. This authorization manager takes required rights into account when they are enforced. This authorization manager is also used by the contextual authorization manager to check script and programming rights but only for the context document/the current secure document. During a macro execution, for example, it is enough to use the contextual authorization manager. Still, when registering components from page contents/objects, the document authorization manager needs to be used. Additionally, this authorization manager allows for checking if a document has a certain required right independent of the author.

In addition to the right, the methods also take an entity type. The main purpose of this parameter is to allow checking if the author has wiki admin right (vs. just space admin), as this right is frequently required by XObjects. This can be achieved by passing EntityType.WIKI. For script right, EntityType.DOCUMENT should be used, and for programming rights, the passed entity type doesn't matter, as programming rights can only be defined on the farm for which the entity type should be null.

    /**
     * Tests if the given context author of the context document has the specified right at the given level, taking the
     * required rights of the document into account.
     *
     * @param right the right to check
     * @param level the level of the right, for example, for admin right, this could be {@link EntityType#DOCUMENT} for
     * admin right directly on the document itself or {@link EntityType#WIKI} for admin right on the whole wiki.
     * @param contextAuthor the author for which rights shall be checked
     * @param contextDocument the document for which the rights shall be checked
     * @return if the context author has the right
     */
    boolean hasAccess(Right right, EntityType level, DocumentReference contextAuthor,
        DocumentReference contextDocument);

    /**
     * Check if the given document has the given required right.
     *
     * @param right the right to check
     * @param level the level of the right
     * @param contextDocument the reference of the context document
     * @return if the document has the required right (independent of the actual author)
     * @throws AuthorizationException if loading the required rights fails
     */
    boolean hasRequiredRight(Right right, EntityType level, DocumentReference contextDocument)
        throws AuthorizationException;

    /**
     * Checks if the given context author of the context document has the specified right at the given level, taking the
     * required rights of the document into account. This function should be used at security checkpoint.
     *
     * @param right the right to check
     * @param level the level of the right, for example, for admin right, this could be {@link EntityType#DOCUMENT} for
     * admin right directly on the document itself or {@link EntityType#WIKI} for admin right on the whole wiki.
     * @param contextAuthor the author for which rights shall be checked
     * @param contextDocument the document for which the rights shall be checked
     * @throws AccessDeniedException if the context author does not have the right
     */
    void checkAccess(Right right, EntityType level, DocumentReference contextAuthor,
        DocumentReference contextDocument) throws AccessDeniedException;

Change current author (since 8.3RC1)

Provided by Role org.xwiki.security.authorization.AuthorExecutor:

    /**
     * Execute the passed {@link Callable} with the rights of the passed user.
     *
     * @param callable the the task to execute
     * @param authorReference the user to check rights on
     * @return computed result
     * @throws Exception if unable to compute a result
     * @param <V> the result type of method <tt>call</tt>
     */
    <V> V call(Callable<V> callable, DocumentReference authorReference) throws Exception;

    /**
     * Setup the context so that following code is executed with provided user rights.
     * 
     * <pre>
     * {@code
     * try (AutoCloseable context = this.executor.before(author)) {
     *   ...
     * }
     * }
     * </pre>
     *
     * @param authorReference the user to check rights on
     * @return the context to restore
     * @see #after(AutoCloseable)
     */
    AutoCloseable before(DocumentReference authorReference);

    /**
     * Restore the context to it's previous state as defined by the provided {@link AutoCloseable}.
     *
     * @param context the context to restore
     * @see #before(DocumentReference)
     */
    void after(AutoCloseable context);

Scripting API (since 6.1RC1)

Provides access to the general and contextual API from script services.
Here are some sample codes:

#if ($services.security.authorization.hasAccess('edit'))
... show some UI that require edit access on the current document by the current user ...
#end
#if ($services.security.authorization.hasAccess('edit', 'xwiki:Sandbox.TestPage1'))
... show some UI that require edit access on Sandbox.TestPage1 document by the current user ...
#end
#if ($services.security.authorization.hasAccess('edit', 'xwiki:XWiki.User1', 'xwiki:Sandbox.TestPage1'))
... show some UI that require edit access on Sandbox.TestPage1 document by XWiki.User1 ...
#end
$services.security.authorization.checkAccess('edit')
... do some task that require edit access ...

checkAccess() versus hasAccess() usage

Both functions provide the same access check but differ in the way the result is reported. While the hasAccess() method will simply offer a true/false answer, the checkAccess() method does not need any return value check since it will throw an AccessDeniedException if the resulting access has been denied.

In the old right service, there was no distinction between access check for UI purposes and access check for really proceeding to action. Only the hasAccess() method was provided. Missing this distinction is not good because:

  • it does not allow easy finding of all critical security access checkpoints where access is checked to ensure security. 
  • it leaves the responsibility of properly checking return values by the caller at these security check points.
  • it leaves the burden of managing access-denied situations individually in all those security checkpoints by the caller.

Therefore, you are strongly encouraged to use the new checkAccess() method everywhere you check access before action. You should refrain from catching the resulting exception. This should be done at a higher level by the UI, which will, therefore, be able to centralize all access check violations. (Obviously, this is a work in progress that we are starting now and will only properly work when the full migration of the old service is completed). Also note that access violations done during checkAccess() are logged. In most situations, this should not happen since the UI or earlier code has already checked the possibility for access and does not provide a path to the prohibited action. Remember that checking the same access several times is no longer costly, so checking access very near the action (even if you think there is no reason it would be denied) is a good security measure to prevent security bugs. This is the purpose of the checkAccess() method.

Some definitions as seen by this module

Entity
An entity is an object on which some actions may be realized. It could be a document, a wiki, a space, or even a xwiki object or property. It may, depending on its nature, contain other entities. All entities being referenced by an EntityReference are supported. Reference to those entities is implemented as SecurityReference (see below).
User
A user is represented by a document entity and could act on entities. Reference to users is implemented as UserSecurityReference.
Group
A group is a user that represents a group of user. A user is considered to receive the rights of all groups it is in, as well as all groups this group is in and that recursively. Reference to group is implemented as GroupSecurityReference.
Wiki
A wiki is an entity that is a root for containing other entities (except wiki). Except for Global user/group (see below), all security information does not interact outside of a wiki. (i.e.: a user of a wiki cannot have access to an entity of another wiki or be a member of a group of another wiki. 
Main Wiki
The main wiki is the first wiki created. It may contain sub-wiki. Access provided at wiki level, on the Main wiki is inherited by all sub-wikis. See SecurityReference below for more information.
Global user/group
A user or group is defined in the main wiki. Such user may receive access to entities of sub-wikis and be members of group in sub-wikis. This is the only wiki that interact with other wikis.
Action
Anything you can code that acts on an entity (general action act on wiki a whole) that you would like to secure.
Right
It is a symbolic representation of authorization to realize actions on an entity. Multiple different actions are usually secured by the same right. For example, the EDIT right allows editing document content and XObject or access rules.
State (of a right)
It represents the state of authorization at a given time, which could be allowed, denied, or undetermined. It is implemented by org.xwiki.security.authorization.RuleState.
Rule
It defined the state of a right for a set of user or group. So, a single rule may contain a single state for a single right (implementation allows multiple rights, but this should not change anything, each right being evaluated individually) for multiple users and groups at the same time.
Level
It represents a level of the hierarchy of EntityReference. Right may be inherited from the upper level, the usual hierarchy being main wiki > wiki>space > document. The authorization module introduces the main wiki root to provided references (see SecurityEntity below), and ensures isolation of wikis (second level), but is entirely dependent on the hierarchy provided for the rest. However, User and Group should be at document level since these are provided as DocumentReference.

Rights and access decisions

The authorization system is now based on two key principles:

  • Declarative definitions of rights are defined and statically stored in an "enum like" class org.xwiki.security.authorization.Right.
  • A configurable org.xwiki.security.authorization.AuthorizationSettler is in charge of interpreting for a given UserSecurityReference (see below), access to those  Right against a hierarchy of SecurityRuleEntry (see below). 

Therefore, settling access decisions is entirely delegated to customizable components that may be introduced by third parties and configured without rebuilding the platform. The component hint of the AuthorizationSettler may be configured from the ConfigurationSource (xwiki.properties) using the key security.authorization.settler. The default hint "default" is implemented by the DefaultAuthorizationSettler. Another experimental PriorityAuthorizationSettler (currently unmaintained, use at your own risk) is also bundled. Both are based on a AbstractAuthorizationSettler which provides a common foundation for merging access provided at each hierarchy level based on a customizable dynamic policy.

Right definitions

Since the settling process is delegated to the AuthorizationSettler, the interpretation of right definitions is up to it, and right definition is only a tool for helping the creation of an expandable authorization settler, allowing new rights to be easily externally defined. New Right maybe registered with the AuthorizationManager using a RightDescription. The meaning of the right definition explained here is mostly pertinent to the default implementation of the AuthorizationSettler. It should generally be followed by any other settler implementation, but this could not be guaranteed.

Name
Define a name that may be used in UI and log messages.
Default state
Define the state of a right when no rule has been defined for this right at any level of the hierarchy.
Tie resolution policy
Define the state a right should take when two opposite rules enter in conflict.
Inheritance override policy
When true, a right allowed by a higher level (ie. wiki) could be denied by a lower level (ie. document).
Implied rights
A set of rights is implied when this right is allowed. This only affect allowance, and not denial.
Targeted entities
A set of EntityType defining the type of entities where this right may be defined. A special farm level, means only on EntityType.WIKI of the Main wiki could be set using a null value. However, when definition is allowed on EntityType.WIKI is always allowed on the Main wiki as well.
Is read only
Is this right could be allowed on read-only wiki? When false, this right should not be allowed on a read-only mode wiki.

Default rights being predefined

The following right are bundled with the authorization modules and are used with the DefaultAuthorizationSettler for primary actions of XWiki.

 Right constant  Right name  Default state  Tie resolution  Inheritance policy  Implied rights  Targeted entities  Read-only  Comments
 VIEW  view  ALLOW  DENY  deniable  none  Wiki, Space, Document  may be allowed  Allow viewing entities
 EDIT  edit  ALLOW  DENY  deniable  VIEW  Wiki, Space, Document  always denied  Allow editing entities
 COMMENT  comment  ALLOW  DENY  deniable  none  Wiki, Space, Document  always denied  Allow commenting entities
 DELETE  delete  DENY  DENY  deniable  XWiki 15.1+ VIEW  Wiki, Space, Document  always denied  Allow deleting entities
 CREATOR  creator  DENY  ALLOW  not deniable  DELETE  Document  always denied  Internal right provided to document creators except if the creator is guest
 LOGIN  login  ALLOW  ALLOW  deniable  none  Wiki  may be allowed  Allow acces to login page
 REGISTER  register  ALLOW  ALLOW  deniable  none  Wiki  always deny  Allow user registration
 SCRIPT  script  DENY  DENY  deniable  none  Wiki, Space, Document  may be allowed  Allow execution of a user written scripts
 ADMIN  admin  DENY  ALLOW  not deniable  LOGIN, VIEW, EDIT, DELETE, REGISTER, COMMENT, SCRIPT  Wiki, Space  may be allowed  Admin user with all basic rights
 PROGRAM  programming  DENY  ALLOW  not deniable  LOGIN, VIEW, EDIT, DELETE, REGISTER, COMMENT, SCRIPT, ADMIN  Main wiki only  may be allowed  Allow programing
 CREATE WIKI  createwiki  DENY  ALLOW  not deniable  none  Main wiki only  always denied  Allow the creation of wikis (since 5.2 M2)

Default right settler additional policies

The default right settler provides the following additional rules during its decision process:

  • A right allowed by a rule matching the user could not be denied by another rule at the same level matching a group containing that user, whatever the tie resolution policy. For example, on the same document, a Rule allowing edit right to userA of groupA, and a Rule denying edit right to groupA enter into conflict. The standard tie resolution policy (which is, for the edit right, to deny access) will apply to any user of groupA while userA will be allowed.  
  • Any rule matching both the user and a group containing the user will be considered a rule matched for the user and will be implied in the above rule.
  • Implied right receives the tie resolution policy, the inheritance override policy, and their kind of matching (user or group) from the right and the rule of the right that has implied them. For example, an edit right implied by an admin right will not be overridden by denying the edit right at a lower level.
  • Implied right does not imply other rights. Implied rights are not recursively applied. This could be seen as a limitation, but this is more of a feature, since it is not difficult to provide the cumulative list of implied right during right definition if this is really the wanted behavior.
  • When a right has been allowed at a given level, it get explicitly denied to anyone else at the same level. For example, suppose edit right is allow at document level to userA only. In that case, it will be denied to any other userB, unless this userB receive an implied edit right with a different inheritance policy at a higher level (userB is admin for example).

Limitations

To optimize the efficiency and memory footprint of the authorization modules, a special "enum like" set and map of Right are provided and used internally. RightSet and RightMap are current based on bit position in longs limiting to 64 the number of supported Right. While adding new Right dynamically is supported, removing Right has been made impossible. This ensures that two different Rights are never allocated the same bit position in a given ClassLoader environment.

API and bridge

The security API is mostly independent of the system in which it is integrated. Apart from the types shown in the interface above, all interaction between the API and the rest of the system is done using some well-defined interfaces. 

Security References

While the API's main interface still uses standard DocumentReference, and EntityReference for your convenience, those are quickly converted to SecurityReference. There is a class hierarchy of them:

  • SecurityReference: a common class used for reference to any entity being secured, could be built based on a #EntityReference#
    • UserSecurityReference: used for users, it could only be built based on a #DocumentReference#
      • GroupSecurityReference: used for groups and based on this class hierarchy, groups are also seen as users by the API.

Compared to normal EntityReference, SecurityReference prepend all references to sub-wiki entities by the main wiki reference. So, all sub-wikis have a root reference to the main wiki, followed by their wiki reference. They also provide convenient methods to access those references, determine the kind of wiki you are in, and access the original reference used to build the SecurityReference

Another difference concerns the null value. There is no acceptable situation where a null value for SecurityReference is valid:

  • A null EntityReference (used for representing the main Wiki) is converted to a SecurityReference really referencing the main wiki. 
  • A null DocumentReference used to represent the public access (Guest user) is also converted to a UserSecurityReference referencing the main wiki (by inheritance of SecurityReference), but since a UserSecurityReference only provides original reference, DocumentReference, its original document reference is null. Thanks to this, the public access is transparently considered as a Global user and follows the path of global users while being managed by the cache, in particular, for sub-wikis.

Since SecurityReference need to know internally the main wiki reference to be built and for their internal work, and there is no way to know the reference of that wiki without being at least a component (unless you link to oldcore, which is excluded), there is no way to construct SecurityReference with new. A SecurityReferenceFactory component is provided in package org.xwiki.security to create new instances of SecurityReference, UserSecurityReference and GroupSecurityReference. This factory uses an internal XWikiBridge interface to retrieve the main wiki reference.

Public bridge interface

Most of the interfaces used to bridge the authorization API with the underlying system are public interfaces.

The firsts are used to acquire rules information and are defined in org.xwiki.security.authorization:

  • SecurityRule which defines a security rule by linking a set of Right (i.e. VIEW), a set of UserSecurityReference, a set of GroupSecurityReference and a RuleState (i.e. Allow)
  • SecurityRuleEntry links a list of SecurityRules with a SecurityReference. It could be empty, meaning no rules are defined for that entity. 
  • SecurityEntryReader is used to acquire SecurityRuleEntrys from the underlying system. XWiki 10.5+ it's possible to extend it by implementing org.xwiki.security.authorization.SecurityEntryReaderExtra components and XWiki 13.10+ it's possible for an installed extension to provide such components.

The seconds are used to manage the invalidation of entries stored in the security cache and are defined in org.xwiki.security.authorization.cache:

  • SecurityCache allows direct access to the SecurityCache to remove outdated entries. This should only be done by a component implementing the SecurityCacheRulesInvalidator interface to avoid conflict with the security cache loader.
  • SecurityCacheRulesInvalidator is in charge of informing the SecurityCache of changes in security rules to properly invalidate outdated cache entries. If the security invalidator does not properly invalidate entries, CacheConflictingException may occur.

    Since the authentication part of the security module (which should be in charge of user/group management) is currently missing, an internal UserBridge interface is also used to get group information. Another internal XWikiBridge interface is used to check if the wiki is in read-only mode and to retrieve the main wiki reference.

Events

XWiki 11.8+ An event org.xwiki.security.authorization.event.RightUpdatedEvent is sent when a modification may impact the result of a right check (modified XWikiRights object, modified group, etc.).

Cache

A cache of name platform.security.authorization.cache is used to cache both security rule entries as well as security access entries that store the result of a right check for a user and document. Its maximum size is 10000 entries by default. Its maximum size can be configured as explained in the cache module documentation. If the system has enough RAM, it is a good idea to set the maximum cache size to at least 3 times the number of documents in the wiki both to improve the performanceXWiki <15.6  and to avoid bugs like . XWiki 15.6+ The security cache should behave more robustly when it is full. It is now only necessary to store security access entries in the actual cache, the rule entries can also be stored in a data structure outside the cache and thus a large capacity is no longer required to ensure that important rule entries aren't disposed by the cache. This means a good cache size for optimal performance would be the number of active users at the same time times the number of documents they frequently access. Note that the latter also includes documents that contain code or documents for which just the title is displayed, e.g., in a navigation or change log. The security cache size shouldn't be set below the number of documents that are frequently accessed, or performance will severely suffer. If in doubt, check the cache statistics to see the hit rate. A hit rate below 80% (maybe even below 90%) can be a sign that performance could be improved with a larger cache. The reason for this is that if there is a miss for a particular page and user, this entry needs to be re-computed, thereby reading at least four, for nested spaces even more, entries from the cache. Even if all these accesses were hits, the whole computation could have been avoided.

The Security Inspector Application provides a visualization of the cache contents and also more explanations how the cache is structured.

XWiki 16.10.1+ A cache of name platform.security.authorization.requiredrights.cache caches required rights (see below). It also has a default maximum size of 10000 entries. Its maximum size can be configured as explained in the cache module documentation. The size of the cache should be at least the number of frequently accessed documents. Cache entries themselves should be tiny, the main memory usage should be from the document references that are used as keys in the cache.

XWiki 16.10.0+

Required Rights

Required rights allow for defining which rights the content of a document needs. While regular content shouldn't require any rights, some technical pages could need script right for Velocity macros, or wiki admin right to allow the definition of a macro or a UI Extension with wiki scope. When required rights are enforced (controlled by a flag in the document), only those rights are allowed in the document authorization manager regardless of whether the last author has more rights. Further, edit rights are denied to any user who does not have those rights. The purpose of required rights is two-fold:

  1. Avoid that when a user with more rights edits a document, malicious content created by a previous author is executed with more rights. If a document doesn't require any rights, script macros, for example, won't be executed independent of the rights of the last author.
  2. Prevent that users without the required right break a page by not allowing them to edit the page. If the last author should lose a required right after editing a page, the page is still broken, but the situation is much easier to detect.

Required rights are stored as XObjects of class XWiki.RequiredRightClass. Required rights are always the same for all translations of a page and defined on the untranslated document. While the API for required rights has been introduced in XWiki 16.10.0, there is no UI in this version yet. Still, it allows extensions depending on XWiki 16.10.0 to use the new APIs and to define required rights for their pages as it contains the necessary changes in the XAR Format Specifications.

The role org.xwiki.security.authorization.requiredrights.DocumentRequiredRightsManager allows retrieving the required rights that are defined on a document. Required rights should never be loaded from a modified document, only from a saved document. This is because there are safeguards to prevent unauthorized modifications of required rights during saving. They prevent users who don't have a certain right to set or remove that right as required right. For this reason, DocumentRequiredRightsManager doesn't allow passing a concrete document instance, only a document reference.

Security Authentication API

See the Authentication API documentation.

Security URL API

See the URL API documentation.

Prerequisites & Installation Instructions

We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager).

You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.

Dependencies

Dependencies for this extension (org.xwiki.platform:xwiki-platform-security-authorization-api 18.4.0):

Get Connected