| --- | |
| title: Implementing Authorization | |
| --- | |
| <!-- | |
| Licensed to the Apache Software Foundation (ASF) under one or more | |
| contributor license agreements. See the NOTICE file distributed with | |
| this work for additional information regarding copyright ownership. | |
| The ASF licenses this file to You under the Apache License, Version 2.0 | |
| (the "License"); you may not use this file except in compliance with | |
| the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| --> | |
| ## How Authorization Works | |
| When a component requests an operation, | |
| the `SecurityManager.authorize` method is invoked. | |
| It is passed the principal of the operation's requester | |
| and a `ResourcePermission`, which describes the operation requested. | |
| The implementation of the `SecurityManager.authorize` method makes a decision as to whether | |
| the principal will be granted permission to carry out the operation. It returns a boolean in which | |
| a return value of `true` permits the operation, and a return value of `false` prevents the operation. | |
| The operation can also throw an `AuthenticationExpiredException`. | |
| In case of an `AuthenticationExpiredException` the @@product_name@@ client code will make one automatic attempt | |
| to re-connect to the member that sent the exception. | |
| A well-designed `authorize` method will have or will have a way of obtaining | |
| a mapping of principals to the operations (in the form of resource permissions) | |
| that they are permitted to do. | |
| ## Resource Permissions | |
| All operations are described by an instance of the `ResourcePermission` class. | |
| A permission contains the `Resource` data member, | |
| which classifies whether the operation as working on | |
| - cache data; value is `DATA` | |
| - the cluster; value is `CLUSTER` | |
| A permission also contains the `Operation` data member, | |
| which classifies whether the operation as | |
| - reading; value is `READ` | |
| - changing information; value is `WRITE` | |
| - making administrative changes; value is `MANAGE` | |
| The operations are not hierarchical; | |
| `MANAGE` does not imply `WRITE`, and `WRITE` does not imply `READ`. | |
| Some `DATA` operations further specify a region name in the permission. | |
| This permits restricting operations on that region to only those | |
| authorized principals. | |
| And within a region, some operations may specify a key. | |
| This permits restricting operations on that key within that region to | |
| only those authorized principals. | |
| Some `CLUSTER` operations further specify a finer-grained | |
| target for the operation. | |
| Specify the target with a string value of: | |
| - `DISK` to target operations that write to a disk store | |
| - `GATEWAY` to target operations that manage gateway senders and receivers | |
| - `QUERY` to target operations that manage both indexes and continuous | |
| queries | |
| - `DEPLOY` to target operations that deploy code to servers | |
| - `LUCENE` to target Lucene index operations | |
| This table classifies the permissions assigned for operations common to | |
| a Client-Server interaction. | |
| | Client Operation | Assigned `ResourcePermission` | |
| |------------------------------------|-------------------------------------| | |
| | get function attribute | CLUSTER:READ | | |
| | create region | DATA:MANAGE | | |
| | destroy region | DATA:MANAGE | | |
| | Region.Keyset | DATA:READ:RegionName | | |
| | Region.query | DATA:READ:RegionName | | |
| | Region.getAll | DATA:READ:RegionName | | |
| | Region.getAll with a list of keys | DATA:READ:RegionName:Key | | |
| | Region.getEntry | DATA:READ:RegionName | | |
| | Region.containsKeyOnServer(key) | DATA:READ:RegionName:Key | | |
| | Region.get(key) | DATA:READ:RegionName:Key | | |
| | Region.registerInterest(key) | DATA:READ:RegionName:Key | | |
| | Region.registerInterest(regex) | DATA:READ:RegionName | | |
| | Region.unregisterInterest(key) | DATA:READ:RegionName:Key | | |
| | Region.unregisterInterest(regex) | DATA:READ:RegionName | | |
| | execute function | Defaults to DATA:WRITE. Override `Function.getRequiredPermissions` to change the permission. | | |
| | clear region | DATA:WRITE:RegionName | | |
| | Region.putAll | DATA:WRITE:RegionName | | |
| | Region.clear | DATA:WRITE:RegionName | | |
| | Region.removeAll | DATA:WRITE:RegionName | | |
| | Region.destroy(key) | DATA:WRITE:RegionName:Key | | |
| | Region.invalidate(key) | DATA:WRITE:RegionName:Key | | |
| | Region.destroy(key) | DATA:WRITE:RegionName:Key | | |
| | Region.put(key) | DATA:WRITE:RegionName:Key | | |
| | Region.replace | DATA:WRITE:RegionName:Key | | |
| | queryService.newCq | DATA:READ:RegionName | | |
| | CqQuery.stop | CLUSTER:MANAGE:QUERY | | |
| This table classifies the permissions assigned for `gfsh` operations. | |
| | `gfsh` Command | Assigned `ResourcePermission` | |
| |----------------------------------------|----------------------------------| | |
| | alter async-event-queue | CLUSTER:MANAGE:DEPLOY | | |
| | alter disk-store | CLUSTER:MANAGE:DISK | | |
| | alter query-service | CLUSTER:MANAGE | | |
| | alter region | DATA:MANAGE:RegionName | | |
| | alter runtime | CLUSTER:MANAGE | | |
| | backup disk-store | DATA:READ and CLUSTER:WRITE:DISK | | |
| | change loglevel | CLUSTER:WRITE | | |
| | clear defined indexes | CLUSTER:MANAGE:QUERY | | |
| | close durable-client | CLUSTER:MANAGE:QUERY | | |
| | close durable-cq | CLUSTER:MANAGE:QUERY | | |
| | compact disk-store | CLUSTER:MANAGE:DISK | | |
| | configure pdx | CLUSTER:MANAGE | | |
| | create async-event-queue | CLUSTER:MANAGE:DEPLOY, plus CLUSTER:WRITE:DISK if the associated region is persistent | | |
| | create defined indexes | CLUSTER:MANAGE:QUERY | | |
| | create disk-store | CLUSTER:MANAGE:DISK | | |
| | create gateway-receiver | CLUSTER:MANAGE:GATEWAY | | |
| | create gateway-sender | CLUSTER:MANAGE:GATEWAY | | |
| | create index | CLUSTER:MANAGE:QUERY | | |
| | create jndi-binding | CLUSTER:MANAGE | | |
| | create lucene index | CLUSTER:MANAGE:LUCENE | | |
| | create region | DATA:MANAGE, plus CLUSTER:WRITE:DISK if the associated region is persistent | | |
| | define index | CLUSTER:MANAGE:QUERY | | |
| | deploy | CLUSTER:MANAGE:DEPLOY | | |
| | describe client | CLUSTER:READ | | |
| | describe config | CLUSTER:READ | | |
| | describe disk-store | CLUSTER:READ | | |
| | describe jndi-binding | CLUSTER:READ | | |
| | describe lucene index | CLUSTER:READ:LUCENE | | |
| | describe member | CLUSTER:READ | | |
| | describe offline-disk-store | CLUSTER:READ | | |
| | describe query-service | CLUSTER:READ | | |
| | describe region | CLUSTER:READ | | |
| | destroy async-event-queue | CLUSTER:MANAGE | | |
| | destroy disk-store | CLUSTER:MANAGE:DISK | | |
| | destroy function | CLUSTER:MANAGE:DEPLOY | | |
| | destroy index | CLUSTER:MANAGE:QUERY | | |
| | destroy jndi-binding | CLUSTER:MANAGE | | |
| | destroy lucene index | CLUSTER:MANAGE:LUCENE | | |
| | destroy region | DATA:MANAGE | | |
| | execute function | Defaults to DATA:WRITE. Override `Function.getRequiredPermissions` to change the permission. | | |
| | export cluster-configuration | CLUSTER:READ | | |
| | export config | CLUSTER:READ | | |
| | export data | CLUSTER:READ | | |
| | export logs | CLUSTER:READ | | |
| | export offline-disk-store | CLUSTER:READ | | |
| | export stack-traces | CLUSTER:READ | | |
| | gc | CLUSTER:MANAGE | | |
| | get ‑key=key1 ‑region=region1 | DATA:READ:RegionName:Key | | |
| | import data | DATA:WRITE:RegionName | | |
| | import cluster-configuration | CLUSTER:MANAGE | | |
| | list async-event-queues | CLUSTER:READ | | |
| | list clients | CLUSTER:READ | | |
| | list deployed | CLUSTER:READ | | |
| | list disk-stores | CLUSTER:READ | | |
| | list durable-cqs | CLUSTER:READ | | |
| | list functions | CLUSTER:READ | | |
| | list gateways | CLUSTER:READ | | |
| | list indexes | CLUSTER:READ:QUERY | | |
| | list jndi-binding | CLUSTER:READ | | |
| | list lucene indexes | CLUSTER:READ:LUCENE | | |
| | list members | CLUSTER:READ | | |
| | list regions | CLUSTER:READ | | |
| | load-balance gateway-sender | CLUSTER:MANAGE:GATEWAY | | |
| | locate entry | DATA:READ:RegionName:Key | | |
| | netstat | CLUSTER:READ | | |
| | pause gateway-sender | CLUSTER:MANAGE:GATEWAY | | |
| | put ‑‑key=key1 ‑‑region=region1 | DATA:WRITE:RegionName:Key | | |
| | query | DATA:READ:RegionName | | |
| | rebalance | DATA:MANAGE | | |
| | remove | DATA:WRITE:RegionName or DATA:WRITE:RegionName:Key | | |
| | resume async-event-queue-dispatcher | CLUSTER:MANAGE | | |
| | resume gateway-sender | CLUSTER:MANAGE:GATEWAY | | |
| | revoke mising-disk-store | CLUSTER:MANAGE:DISK | | |
| | search lucene | DATA:READ:RegionName | | |
| | show dead-locks | CLUSTER:READ | | |
| | show log | CLUSTER:READ | | |
| | show metrics | CLUSTER:READ | | |
| | show missing-disk-stores | CLUSTER:READ | | |
| | show subscription-queue-size | CLUSTER:READ | | |
| | shutdown | CLUSTER:MANAGE | | |
| | start gateway-receiver | CLUSTER:MANAGE:GATEWAY | | |
| | start gateway-sender | CLUSTER:MANAGE:GATEWAY | | |
| | start server | CLUSTER:MANAGE | | |
| | status cluster-config-service | CLUSTER:READ | | |
| | status gateway-receiver | CLUSTER:READ | | |
| | status gateway-sender | CLUSTER:READ | | |
| | status locator | CLUSTER:READ | | |
| | status server | CLUSTER:READ | | |
| | stop gateway-receiver | CLUSTER:MANAGE:GATEWAY | | |
| | stop gateway-receiver | CLUSTER:MANAGE:GATEWAY | | |
| | stop locator | CLUSTER:MANAGE | | |
| | stop server | CLUSTER:MANAGE | | |
| | undeploy | CLUSTER:MANAGE:DEPLOY | | |
| The `gfsh connect` does not have a permission, | |
| as it is the operation that invokes authentication. | |
| These `gfsh` commands do not have permission defined, | |
| as they do not interact with the cluster: | |
| - `gfsh describe connection`, which describes the `gfsh` end of the connection | |
| - `gfsh debug`, which toggles the mode within `gfsh` | |
| - `gfsh exit` | |
| - `gfsh help` | |
| - `gfsh hint` | |
| - `gfsh history` | |
| - `gfsh run`, although individual commands within the script | |
| will go through authorization | |
| - `gfsh set variable` | |
| - `gfsh sh` | |
| - `gfsh sleep` | |
| - `validate offline-disk-store` | |
| - `gfsh version` | |
| This table classifies the permissions assigned for JMX operations. | |
| | JMX Operation | Assigned `ResourcePermission` | |
| |----------------------------------------------|-----------------------------| | |
| | DistributedSystemMXBean.shutdownAllMembers | CLUSTER:MANAGE | | |
| | ManagerMXBean.start | CLUSTER:MANAGE | | |
| | ManagerMXBean.stop | CLUSTER:MANAGE | | |
| | ManagerMXBean.createManager | CLUSTER:MANAGE | | |
| | ManagerMXBean.shutDownMember | CLUSTER:MANAGE | | |
| | Mbeans get attributes | CLUSTER:READ | | |
| | MemberMXBean.showLog | CLUSTER:READ | | |
| | DistributedSystemMXBean.changerAlertLevel | CLUSTER:WRITE | | |
| | ManagerMXBean.setPulseURL | CLUSTER:WRITE | | |
| | ManagerMXBean.setStatusMessage | CLUSTER:WRITE | | |
| | CacheServerMXBean.closeAllContinuousQuery | CLUSTER:MANAGE:QUERY | | |
| | CacheServerMXBean.closeContinuousQuery | CLUSTER:MANAGE:QUERY | | |
| | CacheServerMXBean.executeContinuousQuery | DATA:READ | | |
| | CqQuery.execute | DATA:READ:RegionName and CLUSTER:MANAGE:QUERY | | |
| | CqQuery.executeWithInitialResults | DATA:READ:RegionName and CLUSTER:MANAGE:QUERY | | |
| | DiskStoreMXBean.flush | CLUSTER:MANAGE:DISK | | |
| | DiskStoreMXBean.forceCompaction | CLUSTER:MANAGE:DISK | | |
| | DiskStoreMXBean.forceRoll | CLUSTER:MANAGE:DISK | | |
| | DiskStoreMXBean.setDiskUsageCriticalPercentage | CLUSTER:MANAGE:DISK | | |
| | DiskStoreMXBean.setDiskUsageWarningPercentage | CLUSTER:MANAGE:DISK | | |
| | DistributedSystemMXBean.revokeMissingDiskStores| CLUSTER:MANAGE:DISK | | |
| | DistributedSystemMXBean.setQueryCollectionsDepth| CLUSTER:MANAGE:QUERY | | |
| | DistributedSystemMXBean.setQueryResultSetLimit | CLUSTER:MANAGE:QUERY | | |
| | DistributedSystemMXBean.backupAllMembers | DATA:READ and CLUSTER:WRITE:DISK | | |
| | DistributedSystemMXBean.queryData | DATA:READ | | |
| | DistributedSystemMXBean.queryDataForCompressedResult | DATA:READ | | |
| | GatewayReceiverMXBean.pause | CLUSTER:MANAGE:GATEWAY | | |
| | GatewayReceiverMXBean.rebalance | CLUSTER:MANAGE:GATEWAY | | |
| | GatewayReceiverMXBean.resume | CLUSTER:MANAGE:GATEWAY | | |
| | GatewayReceiverMXBean.start | CLUSTER:MANAGE:GATEWAY | | |
| | GatewayReceiverMXBean.stop | CLUSTER:MANAGE:GATEWAY | | |
| | GatewaySenderMXBean.pause | CLUSTER:MANAGE:GATEWAY | | |
| | GatewaySenderMXBean.rebalance | CLUSTER:MANAGE:GATEWAY | | |
| | GatewaySenderMXBean.resume | CLUSTER:MANAGE:GATEWAY | | |
| | GatewaySenderMXBean.start | CLUSTER:MANAGE:GATEWAY | | |
| | GatewaySenderMXBean.stop | CLUSTER:MANAGE:GATEWAY | | |
| | LockServiceMXBean.becomeLockGrantor | CLUSTER:MANAGE | | |
| | MemberMXBean.compactAllDiskStores | CLUSTER:MANAGE:DISK | | |
| ## Implement Authorization | |
| Complete these items to implement authorization. | |
| - Decide upon an authorization algorithm. | |
| The [Authorization Example](authorization_example) | |
| stores a mapping of which principals (users) are permitted to do | |
| which operations. | |
| The algorithm bases its decision | |
| on a look up of the permissions granted to the principal attempting | |
| the operation. | |
| - Define the `security-manager` property. | |
| See [Enable Security with Property Definitions](enable_security) | |
| for details about this property. | |
| - Implement the `authorize` method of the `SecurityManager` interface. | |
| - Define any extra resources that the implemented authorization algorithm | |
| needs in order to make a decision. | |
| ### Authorization of Function Execution {#AuthorizeFcnExecution} | |
| By default, a function executed on servers requires that the | |
| entity invoking the function have `DATA:WRITE` permission on the | |
| region(s) involved. | |
| Since the default permission may not be appropriate for all functions, | |
| the permissions required may be altered. | |
| To implement a different set of permissions, | |
| override the `Function.getRequiredPermissions()` method | |
| in the function's class. | |
| The method should return a `Collection` of the permissions | |
| required of the entity that invokes an execution of the function. | |
| ### Authorization of Methods Invoked from Queries {#AuthorizeMethodsInQueries} | |
| Enabling the `SecurityManager` affects queries by restricting the methods that a running query may invoke. | |
| See [Method Invocations](../developing/querying_basics/query_select/the_where_clause.md#the_where_clause__section_D2F8D17B52B04895B672E2FCD675A676) and [Method Invocation Authorizers](../security/method_invocation_authorizers) for details. |