<!-- TITLE: How to integrate Security Provider --> # Goals In this tutorial you will learn how to integrate the security provider to enable a login mechanism # Prerequisites This tutorial requires you to complete the following steps / tutorials: - [How to create an application](/phovea/development/create/How-to-create-an-application) # Summary ```bash mkdir <workspace directory> cd <workspace directory> git clone https://github.com/phovea/phovea_server.git -b develop git clone https://github.com/phovea/phovea_security_flask.git -b develop mkdir myapp cd myapp yo phovea:init-app # add extra phovea_security_flask module dependency cd .. yo phovea:workspace npm i docker-compose up -d npm run start:myapp # adapt code, see below ``` # Tutorial ## Setup workspace Firs step is to setup a new workspace and application in which we can integrate the login logic. In addition to the new application `myapp`, both `phovea_server` and `phovea_security_flask` are needed in the workspace for the server side. ```bash mkdir <workspace directory> cd <workspace directory> git clone https://github.com/phovea/phovea_server.git -b develop git clone https://github.com/phovea/phovea_security_flask.git -b develop mkdir myapp cd myapp yo phovea:init-app ``` In the end the wizard should print something like: ![image](/uploads/integrate_security_provider/app.png) ```bash cd .. yo phovea:workspace npm i docker-compose up -d npm run start:myapp ``` open http://localhost:8080 ## Add login menu The previous step created a simple application that we use as a starting point. The next step is to integrate the login menu into the app. Please edit the file `myapp/src/index.ts` according to the given template: ```typescript // ... import LoginMenu from 'phovea_security_flask/src/LoginMenu'; import {currentUser, isLoggedIn} from 'phovea_core/src/security'; const header = createHeader( <HTMLElement>document.querySelector('#caleydoHeader'), { appLink: new AppHeaderLink(APP_NAME) } ); const menu = new LoginMenu(header); header.insertCustomRightMenu(menu.node); menu.on(LoginMenu.EVENT_LOGGED_IN, () => { console.assert(isLoggedIn()); console.log(currentUser()); }); menu.on(LoginMenu.EVENT_LOGGED_OUT, () => { console.assert(!isLoggedIn()); }); // ... ``` We extend the Phovea app header by adding a login menu element to the right menu. The LoginMenu handles the whole login process and fires two events: `LoginMenu.EVENT_LOGGED_IN` and `LoginMenu.EVENT_LOGGED_OUT` accordingly. After updating the application a new item pops up in the right menu bar as in the following screenshots: ![image](/uploads/integrate_security_provider/login_button.png) ![image](/uploads/integrate_security_provider/login_dialog.png) ## Check security on client side The previous example already showed a simple usage of the currently logged in user on the client side. The relevant module is [security.ts](https://github.com/phovea/phovea_core/blob/develop/src/security.ts) from phovea core. Its most important functions are: * `isLoggedIn(): boolean` * `currentUser(): IUser|null` returns the currently logged in user or null if not logged in * `currentUserNameOrAnonymous(): string` returns the named of the currently logged in user or 'anonymous' otherwise * `canRead(item: ISecureItem): boolean` checks whether the currently logged in user has the permission to read the given secure item * `canWrite(item: ISecureItem): boolean` checks whether the currently logged in user has the permission to write the given secure item ## Check security on server side On the server side a similiar module exists: [security.py](https://github.com/phovea/phovea_server/blob/develop/phovea_server/security.py) providing similar features during processing an REST API request. Its most important functions are: * `is_logged_in(): bool` * `current_user(): User` return the currently logged in user or the anonymous user object instead * `current_username: str` return the currently logged in user name or 'anonymous' otherwise * `can_read(item): boolean` * `can_write(item): boolean` * `login_required(f)` decorator (`@login_required`) which requires that the user is logged in before executing the function ## Security Stores The `phovea_security_flask` module is a generic implementation for handling security in phovea based on flask-login, i.e. cookies and user sessions. In addition, security stores are used to actually verify user given by username and password. `phovea_security_flask` comes with a default implementation based on an encrypted configuration. [`phovea_security_store_ldap`](https://github.com/phovea/phovea_security_store_ldap/) is an implementation based on LDAP. The default security provider will be used if no other one is included in the build. Users are configured in the configuration file of the application. By default, two users are defined in the default configuration located at [config.json](https://github.com/phovea/phovea_security_flask/blob/develop/phovea_security_flask/config.json). * admin/admin * sam/sam Salt and passwords can be generated using the [`encryptor.py`](https://github.com/phovea/phovea_security_flask/blob/develop/encryptor.py) utility script. As an alternative the dummy store supports configuring the users via environment variables. During startup it looks for all environment variables starting with `PHOVEA_USER_`. For each matching environment variable a user is generated. The environment variable has to follow the following pattern ```bash PHOVEA_USER_<username>=<salt>;<encrypted_password>[;<role>]* ``` e.g. for the configured admin account: ```bash PHOVEA_USER_admin=dcf46ce914154a44b1557eba91c1f50d;e464485eeeca97927191bd77e38137cc5870c53efb05c8ec027faa8d47f0c0ee23e733ea5e494cb045ca46b0f3b6f695b7261a34f46ba3797cde67724d78522a;admin ``` # Conclusion Lessons learned: - How to integrate security provider in own application - How to add the login menu to your app header - How to check the security on the client side - How to check the security on the server side - How to add a new user to the default security store - How to use a different security store