A prototype Authorization Manager written in Java using an external XACML (eXtensible Access Control Markup Language) authorization engine also known as a Policy Decision Point (PDP) for authorization.
Note: The plugin requires at least version 7.3 of the Curity Identity Server.
The Curity Identity Server can leverage Authorization Managers to control access to exposed GraphQL APIs for DCR and User Management. Authorization Managers can be custom built using the Curity Java Plugin SDK. This is an example of a custom Authorization manager that acts as a Policy Enforcement Point (PEP) in a XACML architecture. The XACML Authorization Manager sends a JSON formatted request to a configured PDP that holds a policy. The PDP responds with a decision or optionally with obligations. The XACML Authorization Manager handles the response and allows/denies access to the requested resource. The XACML Authorization Manager can also filter data and based on the policy in use by the PDP can allow access to the resource but deny access to specific fields within that resource.
Additional details related to this plugin and to Authorization Managers in general is available in this [XACML Authorization Manager]](https://curity.io/resources/learn/xacml-authorization-manager/) article.
Build the plugin by issuing the command mvn package
. This will produce a JAR file in the target/xacml-authorization-manager
directory, which can be installed.
To install the plugin, copy the compiled JAR (and all of its dependencies) from target/xacml-authorization-manager
into ${IDSVR_HOME}/usr/share/plugins/${pluginGroup}
on each node, including the admin node.
For more information about installing plugins, refer to the Plugin Installation section of the Documentation.
For a list of the dependencies and their versions, run mvn dependency:list
. Ensure that all of these are installed in the plugin group; otherwise, they will not be accessible to this plug-in and run-time errors will result.
The plugin needs an HttpClient, host, port and path configured in order to communicate with the XACML PDP.
Name | Type | Description | Example | Default |
---|---|---|---|---|
HttpClient |
String | The ID of the HttpClient that the Authorization Manager will use to call the XACML PDP. | xacml-http-client |
|
PDP Host |
String | The hostname of the XACML PDP. | xacml-pdp.example.com |
localhost |
PDP Port |
String | The port that the XACML PDP is exposing its service on. | 8443 |
8080 |
PDP Path |
String | The path of the XACML PDP that accepts authorization requests. | /pdp |
/services/pdp |
When committed, the Authorization Manager is available to be used throughout the Curity Identity Server.
In order to protect the DCR GraphQL API the Authorization Manager needs to be added to the Token Service Profile. Navigate to Token Service
-> General
, in the drop-down for Authorization Manager, choose the newly created Authorization Manager (my-xacml-authz-manager
in the example above).
In order to protect the User Management GraphQL API the Authorization Manager needs to be added to the User Management Profile. Navigate to User Management
-> General
, in the drop-down for Authorization Manager, choose the newly created Authorization Manager (my-xacml-authz-manager
in the example above).
The repository contains a docker compose file that will run an instance of the Curity Identity Server, a data source with test data and an AuthzForce XACML PDP. Running this environment will provide a fully configured environment that can be used to test the use cases and the plugin.
A script is available that will build and deploy the XACML Authorization Manager Plugin and start the docker containers. Run /deploy.sh
to get everything up and running. Run ./teardown.sh
to stop and remove all the containers.
NOTE DEBUG logging is enabled for the Curity Identity Server and the XACML PDP.
- Using OAuth.tools, initiate a code flow using the
xacml-demo
client (secret isPassword1
). - Log in with a user,
admin
ordemouser
(by default both have the passwordPassword1
). Theadmin
user belongs to the groupadmin
that has full access to the GraphQL APIs. Thedemouser
belongs to thedevops
group that is subject to filtration of certain fields for both DCR and User Management data. This should be clear when reviewing the policy used by the XACML PDP. Note that the group claim is issued by default per the configuration. - The JWT that is obtained from running the code flow can be used in a call to either of the GraphQL APIs. Using for example Postman or Insomnia, construct a query and add the JWT in the
Authorization
header.
query getAccounts
{
accounts(first: 5) {
edges {
node {
id
name {
givenName
middleName
familyName
}
title
active
emails {
value
primary
}
phoneNumbers {
value
primary
}
}
}
}
}
The policies are written in ALFA and available in xacml-pdp/alfa. They are compiled into XACML artifacts using a Visual Studio Code Plugin. The compiled representation of the policies is available in xacml-pdp/pdp/conf/policies/ and loaded by the PDP at startup.
NOTE: The ALFA representation of the policies is much easier to read than the XACML artifacts.
DCR Policies are defined and grouped by the graphQLDCR
policyset where the PDP will check that resourceType == "dcr"
.
If the user has group == "admin"
, access is permitted to all different possible actions (GET, POST, etc.). If the user instead belongs to the devops
group, access is only permitted for a POST
request. Access is also limited by obligations that are returned as part of the response from the PDP for the POST
action.
Access to the User Management API is defined in the graphQLUM
policyset. The structure is very similar to the graphQLDCR
policyset. Here, the phoneNumbers
and name
fields are filtered for users in the devops
group.
To test the PDP alone without the involvement of the Authorization Manager a sample request can be sent using for example Postman.
POST /services/pdp HTTP/1.1
Host: localhost:8080
Content-Type: application/xacml+json
{"Request":
{"Category":[{
"CategoryId":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject",
"Attribute":[{
"AttributeId":"subject-id",
"Value":"alice"
},
{
"AttributeId":"group",
"Value":"devops"
}]
},
{
"CategoryId":"urn:oasis:names:tc:xacml:3.0:attribute-category:action",
"Attribute":[{
"AttributeId":"apiAction",
"Value":"POST"
}]
},
{
"CategoryId":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
"Attribute":[{
"AttributeId":"resourceType",
"Value":"user-management"
}]
}]
}
}
This should return the response below from the PDP that includes an obligation. The obligation itself is defined in the policy and in this case indicates what fields that the Authorization Manager should filter, i.e. name
and phoneNumbers
.
{
"Response": [
{
"Decision": "Permit",
"Obligations": [
{
"AttributeAssignment": [
{
"Value": "true",
"DataType": "http://www.w3.org/2001/XMLSchema#boolean",
"Category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
"AttributeId": "phoneNumbers"
},
{
"Value": "true",
"DataType": "http://www.w3.org/2001/XMLSchema#boolean",
"Category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
"AttributeId": "name"
}
],
"Id": "curity-filters"
}
]
}
]
}
- Please visit curity.io for more information about the Curity Identity Server
- OASIS eXtensible Access Control Markup Language (XACML) TC
- More details on Abbreviated Language For Authorization (ALFA)
- Curity Identity Server GraphQL APIs
- User Management with GraphQL
- Authorizing Access to User Data
Copyright (C) 2022 Curity AB.