Impersonation with webapps#

Concepts#

Webapps can be accessed by any user with the necessary permissions, such as “Read dashboards” or “Read project content” after successfully logging in. You can refer to the Public webapps page if you require further information.

Each time a user uses a webapp, the code is executed on behalf of a user, defined by the “Run backend as” parameter configured in the webapp settings, as illustrated in Figure 1. Therefore, the actions performed by the user are attributed to the user mentioned in the “Run backend as” parameter.

Figure 1: Backend configuration.

Figure 1: Backend configuration.#

For example, if user U1 runs a webapp with the “Run backend as” parameter set to A1, the actions taken by U1 will be identified as actions taken by the user A1. If you need the actions being identified as actions taken by user U1, you must make an impersonation call.

It is essential to consider the security and permission aspects of impersonation while using webapps. You can refer to this documentation to learn more about these aspects.

Impersonation usage#

Impersonation calls work on any web framework so that you can use your preferred web framework. Creating a simple webapp allows you to test, evaluate, and understand how impersonation works. When a job starts, Dataiku logs it. Then, you can observe impersonation by examining a Dataiku project’s interface and jobs section.

To test impersonation, you will create a web application that builds a dataset (i.e., starts a job). You can observe impersonation by examining a Dataiku project’s interface or the jobs section. To carry out this task, you will use the Dataiku TShirts project. To do so:

  1. On the top left corner, click + New project > Sample project > Dataiku TShirts.

  2. On the top navigation bar, navigate to the </> > Webapp section.

  3. Click on + New Webapp and select Code Webapp.

  4. Select the library with which you want to build your webapp.

The webapp aims to build a dataset present in the project; for example, you will build the web_history_prepared dataset.

Implementation#

Codes presented show two ways of getting user information, but there is only one way to do impersonation. You can also get user information by using the impersonation mode.

HTML Code#
1<h1>Impersonation Demo</h1>
2
3<h2>Welcome: <span id="identified_user"></span></h2>
4
5<div class="build_dataset">
6    <form id="form-dataset" novalidate>
7        <button type="button" class="main-blue-button" id="build-button">Build the dataset</button>
8    </form>
9</div>
Javascript code#
 1/*
 2 * For more information, refer to the "Javascript API" documentation:
 3 * https://doc.dataiku.com/dss/latest/api/js/index.html
 4 */
 5
 6let buildButton = document.getElementById('build-button');
 7let identifiedUser = document.getElementById('identified_user')
 8
 9buildButton.addEventListener('click', function (event) {
10    datasetToBuild = "web_history_prepared"
11    $.get(getWebAppBackendUrl("/buil_dataset"), {datasetToBuild: datasetToBuild});
12});
13
14// When loading, get the user information
15$.getJSON(getWebAppBackendUrl('/get_user_name'), function (data) {
16    identifiedUser.textContent = data;
17});
Backend code#
 1import dataiku
 2import pandas as pd
 3from flask import request, jsonify
 4
 5import logging
 6
 7logger = logging.getLogger(__name__)
 8
 9
10# Example:
11# As the Python webapp backend is a Flask app, refer to the Flask
12# documentation for more information about how to adapt this
13# example to your needs.
14# From JavaScript, you can access the defined endpoints using
15# getWebAppBackendUrl('first_api_call')
16
17@app.route('/get_user_name')
18def get_user_name():
19    logger.info("In it")
20    logger.info(request)
21    # Get user information from the request (can be done with impersonation)
22    headers = dict(request.headers)
23    auth_info = dataiku.api_client().get_auth_info_from_browser_headers(headers)
24    return (json.dumps(auth_info.get("associatedDSSUser")))
25
26    # Example of impersonation usage
27
28
29#    with dataiku.WebappImpersonationContext() as ctx:
30#        logger.info('impersonation')
31#        # Using this context, your actions here will be impersonated.
32#        client = dataiku.api_client()
33#        user = client.get_own_user()
34#        settings = user.get_settings()
35#        logger.info(settings.get_raw())
36#        return json.dumps(settings.get_raw().get('displayName'))
37
38
39@app.route('/buil_dataset')
40def build_dataset():
41    dataset = request.args.get('datasetToBuild')
42    logger.info("Impersonation begins...")
43    with dataiku.WebappImpersonationContext() as context:
44        # Each time your need to do impersonation, you need to obtain a client.
45        # Dash cannot store objects that are not in JSON format.
46        local_client = dataiku.api_client()
47        project = local_client.get_default_project()
48        outdataset = project.get_dataset(dataset)
49        outdataset.build()
50
51    logger.info("Impersonation ends...")
52    resp = jsonify(success=True)
53    return resp

Wrapping Up#

Congratulations! You know how to use and implement impersonation for web applications. Permissions and impersonation are critical points for web application security.