User management with GraphQL

User Management with GraphQL

On this page

This tutorial shows how to manage user account data within your applications, by connecting to GraphQL endpoints. When managing user accounts, the Curity Identity Server acts as a Web API, so you must present an access token and use scopes and claims for authorization. In order to provide a secure and flexible solution, there are a few layers, which are explained in the following sections.

Prerequisites

First, ensure that you have an enterprise (or trial) license file, that allows access to GraphQL endpoints for user administration. GraphQL in the Curity Identity Server is currently only supported for JDBC data sources. If you are upgrading from an older version of the Curity Identity Server, make sure the schema is updated to add the database_clients table. The latest SQL schema files are available in any deployment of the Curity Identity Server, in the $IDSVR_HOME/etc folder.

Expose a GraphQL User Endpoint

The User Management Guide provides full details on administering users, and the process starts by creating a User Management Profile. To start using GraphQL to access user accounts, also add an endpoint of type um-graphql-api:

GraphQL Endpoint

Configure a Client Application

A GraphQL client application must be used to administer user accounts. The DevOps dashboard is a built-in GraphQL client, which can be useful to compare against when developing your own app. See the Running the DevOps Dashboard tutorial for a fast working setup.

Configure Access Tokens

Next, you must configure the GraphQL client to use access tokens that will be accepted at the GraphQL user endpoint. Doing so requires an authorization manager to be configured, and you can choose from one of the following methods:

TypeBehavior
Scope Authorization ManagerThe client only needs to configure a scope. All users of the client get the same access to database clients. This has only limited usefulness, such as for a fast development setup.
Groups Authorization ManagerThe client configures a scope and also a groups claim. Different users can be assigned different coarse-grained privileges. This option is usually used in the DevOps dashboard to enable different teams to access the Curity Identity Server.
Attribute Authorization ManagerThe client configures a scope and also a groups claim. Different users can be assigned different fine-grained privileges. This is recommended when an organization uses GraphQL in its own applications.

Ensure that the authorization manager is configured against the User Management Profile. Do this by navigating to ProfilesUser ManagementGeneral. In the Authorization section choose the previously created authorization manager.

GraphQL Account Operations

When getting started, a GraphQL client utility, such as the Insomnia tool, can be used to send requests. The DevOps dashboard example deployment exposes a user management endpoint at the following URL:

text
1
http://localhost:8443/um/graphql/admin

For a fast local development setup, one option is to run the DevOps dashboard, then use browser tools to view network requests. This enables you to quickly get a working access token to paste into the tool:

Insomnia User Token

The request data in the following subsections can be pasted into Insomnia's GraphQL pane and sent to the user management endpoint. After pasting each payload into the tool, click Prettify GraphQL before sending each request, to verify the syntax and ensure that a correct request is sent.

Once the requests and responses are understood, you can begin GraphQL coding against user accounts in your own apps. There are many client libraries available to choose from, in all the main technology stacks. These provide similar features to the Insomnia tool, to enable productive development.

Only active users by default

The default behavior when creating accounts using the GraphQL API is to set active=false (or 0). The default behavior unless explicitly defined is also to only list accounts where active=true (or 1). The result is that an account could be created in one query and if the accounts are listed in a subsequent query, it will not be available.

Either explicitly set active=true when creating the account or include active=false accounts in the query listing users.

Get the Account Schema

You can retrieve the fields available on the main Account object with this GraphQL introspection command, then click the send button:

graphql
12345678
query getAccountSchema {
__type(name:"Account") {
fields {
name
description
}
}
}

The schema can then be browsed to understand the GraphQL queries, mutations, request fields and response fields. These values are also available via intellisense.

Insomnia Account Schema

Use Account Queries

Find a particular user account using one of the lookup methods.

graphql
12345678910111213141516
query findAccount {
accountByEmail(email: "jane.doe@mycompany.com") {
id
name {
givenName
middleName
familyName
formatted
}
preferredLanguage
displayName
linkedAccounts {
value
}
}
}

The results are then returned in the standard GraphQL JSON response format, containing the fields requested within a data section:

json
12345678910111213141516
{
"data": {
"accountByEmail": {
"id": "4d807914-ab51-11ec-b593-0242ac170002",
"name": {
"givenName": "Jane",
"middleName": null,
"familyName": "Doe",
"formatted": "Jane Doe"
},
"preferredLanguage": null,
"displayName": null,
"linkedAccounts": []
}
}
}

Pagination can be used when working with lists, to ensure that queries are efficient. Select a list of the first 10 user accounts like this:

graphql
12345678910111213141516171819
query getAccounts {
accounts(first: 10) {
edges {
node {
id
name {
givenName
middleName
familyName
}
userName
emails {
value
primary
}
}
}
}
}

User Account Mutations

To make data changing commands you can use GraphQL mutations. When creating a user account you can optionally also set a password:

graphql
12345678910111213141516171819
mutation createAccount {
createAccount(input: {
fields: {
userName: "john.doe",
password: "Password1",
emails: {
value: "john.doe@mycompany.com",
primary: true
}
}
}) {
account {
userName
emails {
value
}
}
}
}

The following example shows an update operation for a user account whose name has changed, so that the userName, displayName and email fields are all set to new values:

graphql
1234567891011121314151617181920
mutation updateAccount {
updateAccountById(input: {
accountId: "fbea947a-aabc-11ec-adcb-0242ac170002",
fields: {
userName: "jane.smith"
displayName: "jane.smith"
emails: {
value: "jane.smith@mycompany.com"
primary: true
}
}
}) {
account {
displayName
emails {
value
}
}
}
}

Finally, user accounts can be deleted with the following syntax:

graphql
1234567
mutation deleteAccount {
deleteAccountById(input: {
accountId: "fbea947a-aabc-11ec-adcb-0242ac170002"
}) {
deleted
}
}

There are potentially many other GraphQL features you can use, to put you in better control of your identity data, though the above examples will enable you to get connected.

Custom User Account Fields

Starting in version 7.2 of the Curity Identity Server, GraphQL can be used to save custom fields against user accounts. First you need to define custom fields in the Admin UI under ProfilesUser ManagementGeneral. The following example extends the GraphQL schema to add a string field and a numeric field:

Graphql Custom Fields

You can then run a mutation of the following form to populate the custom fields for a user and save them to the user account data. This example query also echoes back the values in the mutation response.

graphql
1234567891011121314
mutation updateAccount {
updateAccountById(input: {
accountId: "4d807914-ab51-11ec-b593-0242ac170002",
fields: {
Custom1: "A string value"
Custom2: 123
}
}) {
account {
Custom1
Custom2
}
}
}

The custom values are then saved within the attributes column of the data row for the user account, and can be retrieved in the same way as any other GraphQL field. The custom fields can then be used during authentication, and issued to OAuth tokens when required. The Working with Claims tutorial describes how to include custom values from user account data in access tokens.

Users and Dynamic Clients

In some security use cases, Dynamic Client Registration (DCR) is used to register one or more distinct OAuth clients per user. This technique is described in Mobile Best Practices, where a separate dynamic client is registered per user and device. The Authenticated DCR mobile code example provides a working end-to-end solution.

From version 7.2 of the Curity Identity Server, dynamic clients mapped to users can also be accessed using GraphQL. First enable access to the additional data under ProfilesUser ManagementGeneral:

Graphql DCR Data

You can then use GraphQL to read details from the dynamically_registered_clients database table. The result set could potentially contain multiple dynamic clients per user, and the DCR fields are described in the Using Dynamic Client Registration article.

graphql
12345678910111213141516
query findAccount {
accountByEmail(email: "demo@user.com") {
id
name {
givenName
familyName
}
emails {
value
}
dynamicClients {
client_id
scope
}
}
}

All of this data can then be accessed for any user with an account record. As for other areas of the schema, GraphQL tooling will enable you to easily see which DCR fields are available:

GraphQL Advanced Query

Conclusion

User account information stored in the Curity Identity Server can be securely exposed to your own clients. GraphQL endpoints provide a friendly API with modern tooling for developers, though SCIM endpoints are also available, and may be a better choice for some types of operation. To use GraphQL you must also configure an authorization manager, to enable the right permissions to be assigned to each client and user.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial