Package org.apache.wiki.auth

# Interface AuthorizationManager

All Superinterfaces:
  `org.apache.wiki.api.engine.Initializable`

All Known Implementing Classes:
  `DefaultAuthorizationManager`

public interface AuthorizationManager extends org.apache.wiki.api.engine.Initializable

Manages all access control and authorization; determines what authenticated users are allowed to do.

Privileges in JSPWiki are expressed as Java-standard `Permission` classes. There are two types of permissions:

- `WikiPermission` - privileges that apply to an entire wiki instance: e.g., editing user profiles, creating pages, creating groups
- `PagePermission` - privileges that apply to a single wiki page or range of pages: e.g., reading, editing, renaming

Calling classes determine whether they are entitled to perform a particular action by constructing the appropriate permission first, then passing it and the current `Session` to the `checkPermission(Session, Permission)` method. If the session's Subject possesses the permission, the action is allowed.

For WikiPermissions, the decision criteria is relatively simple: the caller either possesses the permission, as granted by the wiki security policy -- or not.

For PagePermissions, the logic is exactly the same if the page being checked does not have an access control list. However, if the page does have an ACL, the authorization decision is made based the union of the permissions granted in the ACL and in the security policy. In other words, the user must be named in the ACL (or belong to a group or role that is named in the ACL) and be granted (at least) the same permission in the security policy. We do this to prevent a user from gaining more permissions than they already have, based on the security policy.

See the implementation on `checkPermission(Session, Permission)` method for more information on the authorization logic.

Since:
  2.3
See Also:
  - `AuthenticationManager`

## Field Summary

Fields
Modifier and Type
Field
Description
`static final String`
`DEFAULT_AUTHORIZER`
The default external Authorizer is the `WebContainerAuthorizer`
`static final String`
`DEFAULT_POLICY`
Name of the default security policy file, in WEB-INF.
`static final String`
`POLICY`
Property that supplies the security policy file name, in WEB-INF.
`static final String`
`PROP_AUTHORIZER`
The property name in jspwiki.properties for specifying the external `Authorizer`.

## Method Summary

Modifier and Type
Method
Description
`void`
`addWikiEventListener(org.apache.wiki.event.WikiEventListener listener)`
Registers a WikiEventListener with this instance.
`boolean`
`allowedByLocalPolicy(Principal[] principals, Permission permission)`
Checks to see if the local security policy allows a particular static Permission.
`boolean`
`checkPermission(org.apache.wiki.api.core.Session session, Permission permission)`
Returns `true` or `false`, depending on whether a Permission is allowed for the Subject associated with a supplied Session.
`boolean`
`checkStaticPermission(org.apache.wiki.api.core.Session session, Permission permission)`
Determines whether a Subject possesses a given "static" Permission as defined in the security policy file.
`default void`
`fireEvent(int type, Principal user, Object permission)`
Fires a WikiSecurityEvent of the provided type, user, and permission to all registered listeners.
`Authorizer`
`getAuthorizer()`
Returns the current external `Authorizer` in use.
`default boolean`
`hasAccess(org.apache.wiki.api.core.Context context, jakarta.servlet.http.HttpServletResponse response)`
Checks whether the current user has access to the wiki context, by obtaining the required Permission (`Command.requiredPermission()`) and delegating the access check to `checkPermission(Session, Permission)`.
`boolean`
`hasAccess(org.apache.wiki.api.core.Context context, jakarta.servlet.http.HttpServletResponse response, boolean redirect)`
Checks whether the current user has access to the wiki context (and optionally redirects if not), by obtaining the required Permission (`Command.requiredPermission()`) and delegating the access check to `checkPermission(Session, Permission)`.
`boolean`
`hasRoleOrPrincipal(org.apache.wiki.api.core.Session session, Principal principal)`
Determines if the Subject associated with a supplied Session contains a desired user Principal or built-in Role principal, OR is a member a Group or external Role.
`default boolean`
`isUserInRole(org.apache.wiki.api.core.Session session, Principal principal)`
Determines if the Subject associated with a supplied Session contains a desired Role or GroupPrincipal.
`void`
`removeWikiEventListener(org.apache.wiki.event.WikiEventListener listener)`
Un-registers a WikiEventListener with this instance.
`Principal`
`resolvePrincipal(String name)`
Given a supplied string representing a Principal's name from an Acl, this method resolves the correct type of Principal (role, group, or user).

### Methods inherited from interface org.apache.wiki.api.engine.Initializable

`initialize`

## Field Details

### DEFAULT_AUTHORIZER

static final String DEFAULT_AUTHORIZER
The default external Authorizer is the `WebContainerAuthorizer`

See Also:
  - Constant Field Values

### POLICY

static final String POLICY
Property that supplies the security policy file name, in WEB-INF.

See Also:
  - Constant Field Values

### DEFAULT_POLICY

static final String DEFAULT_POLICY
Name of the default security policy file, in WEB-INF.

See Also:
  - Constant Field Values

### PROP_AUTHORIZER

static final String PROP_AUTHORIZER
The property name in jspwiki.properties for specifying the external `Authorizer`.

See Also:
  - Constant Field Values

## Method Details

### checkPermission

boolean checkPermission(org.apache.wiki.api.core.Session session, Permission permission)
Returns `true` or `false`, depending on whether a Permission is allowed for the Subject associated with a supplied Session. The access control algorithm works this way:

1. The `Acl` for the page is obtained
2. The Subject associated with the current `Session` is obtained
3. If the Subject's Principal set includes the Role Principal that is the administrator group, always allow the Permission
4. For all permissions, check to see if the Permission is allowed according to the default security policy. If it isn't, deny the permission and halt further processing.
5. If there is an Acl, get the list of Principals assigned this Permission in the Acl: these will be role, group or user Principals, or `UnresolvedPrincipal`s (see below). Then iterate through the Subject's Principal set and determine whether the user (Subject) possesses any one of these specified Roles or Principals.

Note that when iterating through the Acl's list of authorized Principals, it is possible that one or more of the Acl's Principal entries are of type `UnresolvedPrincipal`. This means that the last time the ACL was read, the Principal (user, built-in Role, authorizer Role, or wiki Group) could not be resolved: the Role was not valid, the user wasn't found in the UserDatabase, or the Group wasn't known to (e.g., cached) in the GroupManager. If an `UnresolvedPrincipal` is encountered, this method will attempt to resolve it first before checking to see if the Subject possesses this principal, by calling `resolvePrincipal(String)`. If the (re-)resolution does not succeed, the access check for the principal will fail by definition (the Subject should never contain UnresolvedPrincipals).

If security not set to JAAS, will return true.

Parameters:
  `session` - the current wiki session
  `permission` - the Permission being checked
Returns:
  the result of the Permission check

### isUserInRole

default boolean isUserInRole(org.apache.wiki.api.core.Session session, Principal principal)

Determines if the Subject associated with a supplied Session contains a desired Role or GroupPrincipal. The algorithm simply checks to see if the Subject possesses the Role or GroupPrincipal it in its Principal set. Note that any user (anonymous, asserted, authenticated) can possess a built-in role. But a user must be authenticated to possess a role other than one of the built-in ones. We do this to prevent privilege escalation.

For all other cases, this method returns `false`.

Note that this method does not consult the external Authorizer or GroupManager; it relies on the Principals that have been injected into the user's Subject at login time, or after group creation/modification/deletion.

Parameters:
  `session` - the current wiki session, which must be non-null. If null, the result of this method always returns `false`
  `principal` - the Principal (role or group principal) to look for, which must be non-`null`. If `null`, the result of this method always returns `false`
Returns:
  `true` if the Subject supplied with the WikiContext posesses the Role or GroupPrincipal, `false` otherwise

### getAuthorizer

Authorizer getAuthorizer() throws WikiSecurityException
Returns the current external `Authorizer` in use. This method is guaranteed to return a properly-initialized Authorizer, unless it could not be initialized. In that case, this method throws a `WikiSecurityException`.

Returns:
  the current Authorizer
Throws:
  `WikiSecurityException` - if the Authorizer could not be initialized

### hasRoleOrPrincipal

boolean hasRoleOrPrincipal(org.apache.wiki.api.core.Session session, Principal principal)

Determines if the Subject associated with a supplied Session contains a desired user Principal or built-in Role principal, OR is a member a Group or external Role. The rules are as follows:

1. First, if desired Principal is a Role or GroupPrincipal, delegate to `isUserInRole(Session, Principal)` and return the result.
2. Otherwise, we're looking for a user Principal, so iterate through the Principal set and see if any share the same name as the one we are looking for.

Note: if the Principal parameter is a user principal, the session must be authenticated in order for the user to "possess it". Anonymous or asserted sessions will never posseess a named user principal.

Parameters:
  `session` - the current wiki session, which must be non-null. If null, the result of this method always returns `false`
  `principal` - the Principal (role, group, or user principal) to look for, which must be non-null. If null, the result of this method always returns `false`
Returns:
  `true` if the Subject supplied with the WikiContext posesses the Role, GroupPrincipal or desired user Principal, `false` otherwise

### hasAccess

default boolean hasAccess(org.apache.wiki.api.core.Context context, jakarta.servlet.http.HttpServletResponse response) throws IOException
Checks whether the current user has access to the wiki context, by obtaining the required Permission (`Command.requiredPermission()`) and delegating the access check to `checkPermission(Session, Permission)`. If the user is allowed, this method returns `true`; `false` otherwise. If access is allowed, the wiki context will be added to the request as an attribute with the key name `Context.ATTR_CONTEXT`. Note that this method will automatically redirect the user to a login or error page, as appropriate, if access fails. This is NOT guaranteed to be default behavior in the future.

Parameters:
  `context` - wiki context to check if it is accesible
  `response` - the http response
Returns:
  the result of the access check
Throws:
  `IOException` - In case something goes wrong

### hasAccess

boolean hasAccess(org.apache.wiki.api.core.Context context, jakarta.servlet.http.HttpServletResponse response, boolean redirect) throws IOException
Checks whether the current user has access to the wiki context (and optionally redirects if not), by obtaining the required Permission (`Command.requiredPermission()`) and delegating the access check to `checkPermission(Session, Permission)`. If the user is allowed, this method returns `true`; `false` otherwise. Also, the wiki context will be added to the request as attribute with the key name `Context.ATTR_CONTEXT`.

Parameters:
  `context` - wiki context to check if it is accesible
  `response` - The servlet response object
  `redirect` - If true, makes an automatic redirect to the response
Returns:
  the result of the access check
Throws:
  `IOException` - If something goes wrong

### allowedByLocalPolicy

boolean allowedByLocalPolicy(Principal[] principals, Permission permission)
Checks to see if the local security policy allows a particular static Permission. Do not use this method for normal permission checks; use `checkPermission(Session, Permission)` instead.

Parameters:
  `principals` - the Principals to check
  `permission` - the Permission
Returns:
  the result

### checkStaticPermission

boolean checkStaticPermission(org.apache.wiki.api.core.Session session, Permission permission)
Determines whether a Subject possesses a given "static" Permission as defined in the security policy file. This method uses standard Java 2 security calls to do its work. Note that the current access control context's `codeBase` is effectively this class, not that of the caller. Therefore, this method will work best when what matters in the policy is who makes the permission check, not what the caller's code source is. Internally, this method works by executing `Subject.doAsPrivileged` with a privileged action that simply calls `AccessController.checkPermission(Permission)`.

Parameters:
  `session` - the Session whose permission status is being queried
  `permission` - the Permission the Subject must possess
Returns:
  `true` if the Subject possesses the permission, `false` otherwise
See Also:
  - `. A caught exception (or lack thereof) determines whether the privilege is absent (or present).`

### resolvePrincipal

Principal resolvePrincipal(String name)

Given a supplied string representing a Principal's name from an Acl, this method resolves the correct type of Principal (role, group, or user). This method is guaranteed to always return a Principal. The algorithm is straightforward:

1. If the name matches one of the built-in `Role` names, return that built-in Role
2. If the name matches one supplied by the current `Authorizer`, return that Role
3. If the name matches a group managed by the current `GroupManager`, return that Group
4. Otherwise, assume that the name represents a user principal. Using the current `UserDatabase`, find the first user who matches the supplied name by calling `UserDatabase.find(String)`.
5. Finally, if a user cannot be found, manufacture and return a generic `UnresolvedPrincipal`

Parameters:
  `name` - the name of the Principal to resolve. Note: as of v3.0.0, the underlying behavior has changed. Principals can be resolved via login names only.
Returns:
  the fully-resolved Principal

### addWikiEventListener

void addWikiEventListener(org.apache.wiki.event.WikiEventListener listener)
Registers a WikiEventListener with this instance.

Parameters:
  `listener` - the event listener

### removeWikiEventListener

void removeWikiEventListener(org.apache.wiki.event.WikiEventListener listener)
Un-registers a WikiEventListener with this instance.

Parameters:
  `listener` - the event listener

### fireEvent

default void fireEvent(int type, Principal user, Object permission)
Fires a WikiSecurityEvent of the provided type, user, and permission to all registered listeners.

Parameters:
  `type` - the event type to be fired
  `user` - the user associated with the event
  `permission` - the permission the subject must possess
See Also:
  - `WikiSecurityEvent`