A REST interface for FreeIPA
Plugged In
If you have ever submitted a request to the FreeIPA framework, you will be aware that most actions are only successful if preceded by successful authentication. This can be done either with Kerberos or a password. Initially it makes no difference whether authentication is via the web interface or the ipa
command-line tool. The JavaScript-based web application runs within the calling browser, and all instructions for the framework ultimately take place within the scope of a secure HTTPS connection using JSON-RPC. The ipa
tool uses the framework's Python API to abstract access. If you want to use this API, you need to install the free-ipa-python (ipa-python) package to import the ipalib
module into your scripts.
Querying the framework directly via the JSON-RPC API is especially useful for access from a system that is not part of the FreeIPA domain. This is the case, for example, if another web tool is to be used to read or manipulate data from the server. A query always comprises the desired method followed by an array of arguments and options. The method names of the JSON-RPC API are identical to those of the Python API. For example, a FreeIPA User plugin provides classes for user management. The individual class names are identical to the arguments that need to be passed in to the ipa
tool. For example, the statement for creating a new user is
ipa user-add
The corresponding class in the Python API is therefore user_add
. And this is also the name of the method to be used for accessing the JSON-RPC interface.
An API browser that describes each of these methods has existed within the graphical web interface since FreeIPA version 4.2 (Figure 1). Otherwise, it is also possible to invoke the ipa
tool in verbose mode (-vv
option). The output shows the method used, along with the parameters (Listing 1).
Listing 1: Call to ipa in Verbose Mode
# ipa -vv user-add --first foo --last bar foobar [...] ipa: INFO: Forwarding 'user_add' to json server 'https://ipa01.example.com/ipa/session/json' ipa: INFO: Request: { "id": 0, "method": "user_add", "params": [ [ "foobar" ], { "all": false, "cn": "foo bar", "displayname": "foo bar", "gecos": "foo bar", "givenname": "foo", "initials": "fb", "krbprincipalname": "foobar@EXAMPLE.COM", "no_members": false, "noprivate": false, "random": false, "raw": false, "sn": "bar", "version": "2.156" } ] } [...]
Access via JSON-RPC
To create the user via direct access to the JSON-RPC API, the calls need to be converted to corresponding HTTPS requests. In this example, I am using the curl
command-line browser. Before you start developing a matching script, bear in mind that FreeIPA provides two different entry points for authenticating a user. Thus, it is possible to log on a user by means of a Kerberos ticket or a simple password. The two entry points are:
https://$IPAHOSTNAME/ipa/session/login_kerberos https://$IPAHOSTNAME/ipa/session/login_password
You also need to bear in mind that users are authenticated in advance and the server provides a session cookie that is used during the call to the desired method. Additionally, FreeIPA requires an HTTP referrer that points to the IPA server itself. This prevents cross-site request forgery (XCRF/CSRF) attacks.
For access to work over a secure HTTPS channel, you need to provide the certificate authority (CA) certificate of the FreeIPA system. Additionally, a Kerberos configuration file is required for the client to authenticate a user using a Kerberos ticket. In the simplest case, this file is just copied from a FreeIPA system. To avoid collisions with another Kerberos configuration, an alternative file name is selected; this is then communicated to the system using the KRB5_CONFIG
environmental variable.
JSON-RPC Shell Script
The sample script in Listing 2 implements all of these requirements. The script is designed to create a new user by means of a direct request to the JSON-RPC API of the identity management (IdM) framework. The user must authenticate on the first call. This is achieved either by means of Kerberos or by using a regular user password. In the first case, a corresponding ticket-granting ticket (TGT) is requested from the IdM system's Kerberos server using kinit
, which is later used to request a matching service ticket for the IPA system. To authenticate using a regular user password, a simple form-based login takes place. The entered username and password are transmitted to the server by means of a POST
instruction. If the login works out, a cookie can be used for authorization when calling the user_add
method.
Listing 2: Creating a New User via the API
#!/bin/sh export COOKIEJAR=/tmp/ipa-$$ export IPAHOSTNAME=ipa01.example.com if [ $# -ne 1 ]; then echo -e "Please enter krb or pass as argument." && exit 1 fi # User authentication if there is no cookie. if [ ! -f $COOKIEJAR ] ; then if [ $1 = "krb" ] ; then export KRB5_CONFIG=/etc/krb5-ipa.conf kinit admin curl -v \ -H referer:https://$IPAHOSTNAME/ipa \ -c $COOKIEJAR -b $COOKIEJAR \ --cacert /etc/ipa/ca.crt \ --negotiate -u : \ -X POST https://$IPAHOSTNAME/ipa/session/login_kerberos else read -p "Please enter user name: " username read -s -p "Please enter password: " password curl -v \ -H referer:https://$IPAHOSTNAME/ipa \ -H "Content-Type:application/ x-www-form-urlencoded" \ -H "Accept:text/plain"\ -c $COOKIEJAR -b $COOKIEJAR \ --cacert /etc/ipa/ca.crt \ --data "user=$username&password=$password" \ -X POST https://$IPAHOSTNAME/ipa/session/login_password fi fi # Call to actual method curl -v \ -H referer:https://$IPAHOSTNAME/ipa \ -H "Content-Type:application/json" \ -H "Accept:applicaton/json" \ -c $COOKIEJAR -b $COOKIEJAR \ --cacert /etc/ipa/ca.crt \ -d '{"method":"user_add","params":[["foobar"],{ "cn": "foo bar", "displayname": "foo bar", "gecos": "foo bar", "givenname": "foo", "initials": "fb", "krbprincipalname": "foobar@EXAMPLE.COM", "no_members": false, "noprivate": false, "random": false, "raw": false, "sn": "bar" }],"id":0}' -X POST https://$IPAHOSTNAME/ipa/session/json
Cookies are used to store the authentication information, which curl
saves in a file. Following the -b
option, curl
expects a cookie file that it uses for a request; -c
is followed by a file in which curl
stores the cookies delivered by the server. The same file, /tmp/ipa-$$
, is used twice here; the $$
characters in the shell script stand for the current process ID.
Conclusions
Users typically access the FreeIPA identity management framework via a graphical web interface or a command-line tool. Direct access to the IdM system's JSON-RPC API is better suited for automating tasks or running batch jobs. Thanks to the new API browser, the individual methods and available parameters are very well documented.