Interoperability FreeIPA REST Interface Lead image: Lead Image © P.Gudella, 123RF.com
Lead Image © P.Gudella, 123RF.com
 

A REST interface for FreeIPA

Plugged In

Access to the FreeIPA identity management framework is usually handled via a graphical web interface or a command-line tool, but the framework can also be queried directly via the JSON-RPC API. By Thorsten Scherf

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"
      }
   ]
}
[...]
An API browser within the web interface describes the individual API methods.
Figure 1: An API browser within the web interface describes the individual API methods.

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.