Dashboard Authentication and Authorisation

Authentication module (dashboard.auth)

This module's purpose is to set up the CERN SSO Portal over any dashboard application automatically.

This portal allows the user to log in with his CERN account credentials, his Windows or Kerberos credentials, his certificate, a public service account or an organization or institution account (as long as these have been authorized). It also allows the administrator to choose which ADFS groups he wants to give access to his application.

A presentation destined for developers has been created for a section meeting and stored here.

Requirements

Apache httpd with SSL configured correctly is required for this module to work.

See here for instructions on getting the certificates and here for instructions on setting up SSL.

You also need to register your application and manage the permissions via the Cern SSO management page

This step is crucial. Be sure to configure your application permissions correctly.

Installation

As root, run the following command lines :

yum install dashboard-auth

service shibd start

service httpd restart

Result

By default, the module installs the portal over the whole application with all the aforementioned authentication methods available :

Further configurations

It is possible to choose a specific method of authentication and allow specific ADFS groups for certain specific path.

To do this, first open the following file for edition :

/opt/dashboard/etc/dashboard-web/dashboard-auth.cfg

In this configuration file, you can edit and add lines in the [loctosecure] section.

Only one path per line is allowed and top path rules will affect the subpath rules unless otherwise specified by other lines.

The format of the lines needs to follow this pattern (with the colons ":") :

folderpath : authenticationmethod [: ADFSGroup1, ADFSGroup2, ...]

  • The folder path is the path to secure. It starts with "/".
  • The authentication method can be either of those options. If you choose one specific method, it will be the only one displayed to the user and the other method will not be available to him :
    • all
    • Forms
    • Kerberos
    • Certificates
    • Two_Factor
  • The ADFS groups are optional and there is no limit, although adding too many E-Groups is not recommended because it will simply kill the application due to the very large generated header size containing the User Token.
    They must be separated by commas (",")

by default, the following line is already in the file :

/ : all

Once the changes made, the following line (python script) has to be run :

python /opt/dashboard/lib/dashboard/http/actions/auth/ChangeAuthMethod.py

and httpd has to be restarted :

service httpd restart

AuthoriseAction

This class provides the methods for retrieving useful user's informations :

  • getCurrentUser
  • getCurrentUserWithGroups
Right now, it is currently possible to retrieve the user's :
  • full name
  • DNstring (in case of certificate authentication)
  • e-mail
  • e-groups
The full name, DNstring and e-mail are provided by getCurrentUser

The full name, DNstring, e-mail and e-groups are provided by getCurrentUserWithGroups

It is however very easy to edit the methods or add new methods in order to retrieve more informations about the user.

The environment variables set after authentication and containing informations about the user are :

  • "ADFS_GROUP"
  • "ADFS_EMAIL"
  • "ADFS_LOGIN"
  • "ADFS_FULLNAME"
  • "ADFS_PHONENUMBER"
  • "ADFS_FAXNUMBER"
  • "ADFS_MOBILENUMBER"
  • "ADFS_BUILDING"
  • "ADFS_FIRSTNAME"
  • "ADFS_LASTNAME"
  • "ADFS_DEPARTMENT"
  • "ADFS_HOMEINSTITUTE"
  • "ADFS_HOMEDIR"
  • "ADFS_PERSONID"
  • "ADFS_PREFERREDLANGUAGE"
  • "ADFS_ROLE"
  • "ADFS_IDENTITYCLASS"
  • "ADFS_FEDERATION"
  • "ADFS_AUTHLEVEL"

Future possible works

Integrate OAuth 2 Authorization Service

Integrate module Auth Mellon

Authorisation module (dashboard.authorise)

This module is a generic access control system which can be used in many different applications.

At the moment, the module itself needs to have the user in his database in order to work properly. In the future, what would be great is that logged in users that are in an e-group get the permissions applied to this group, even if the aren't in the database yet. This could be done by adding a new "hasPermission" function that gets the only the groups of the user without the user himself.

Here is a powerpoint presentation made for the developer's

Installation

The installation of the module is simple, just write the command:

  • yum install dashboard-authorise
Once you have it, you need to run the database SQL script of the module which is in the directory "dashboard.authorise/config/db".

Database schema

  • AUTHORISE_USERS
This table will contain the users of my access control system. There are only 3 different columns in the schema, but we are free to add any needed column like “joinDate” or “lastConnexion” and so on. One important thing to notice is that “userName”, “userDN” and “email” fields MUST be unique.

  • AUTHORISE_GROUPS
This table will contain the groups of the system. In this schema, each user can have multiple groups. Each user will also have a base group with the same name than the “userName”. One important thing to notice is that both “groupName” and “egroupName” fields MUST be unique.

  • AUTHORISE_USERS_GROUPS
This table maps the users and the groups in order to have multiple groups per user and vice-versa.

  • AUTHORISE_PERMISSIONS
This table contains the permissions. Each permission possesses one group ID in order to link the it to the user.

This schema is somehow standard, users can have multiple groups and there are permissions for specifics groups. The important thing in this schema is the “value” attribute of the “AUTHORISE_ PERMISSIONS” table. This value will be set like this:

  • <object>.<permission>.<id>
More information in the below chapter.

Permission value

  • <object>.<permission>.<id>
<object> will specify on what the right applies, for instance “admin”, “metric”, “view”, …
<permission> will be a value that specify the right, for instance “add”, “modify” or “remove”.
<id> specifies the id of the object that the user has the right on. If the <id> parameter is set to %, the user has the right on the whole table.

There is a special caracter which is %. This caracter means "all", for instance if someone has the permission "user.%", he will have all the permissions (add, update.<id>, remove.<id>) on every users. Also the permission value "%" is the one for the administrators.
Sometimes the <id> fields makes simply no sense, for instance the "add" permission, you can use "user.add" without the id.
Also you are free to add as many levels as you want in the permission value, for instance <object>.<object>.<permission>.<id>. The only restriction is that for a given object, all of them must have the same amount of levels. The reason is that, for instance, if you have special users and normal users and someone has the permission "user.%.1". This person will be able to modify "user.update.1" but also "user.special.update.1" which can be dangerous. You should give the permission "user.normal.%.1" instead.

Example

Imagine someone wants to modify the name of the user number 1. The permission value that is created to check if he can do it is : user.update.1

Now all of the permissions in the above list will work for this case:

  • user.update.1
    • Permission to modify the user number 1 only.
  • user.update.%
    • Permission to modify every user in the database.
  • user.%.1
    • Permission to do whatever with the user number 1 (update, remove, ...).
  • user.%
    • Permission to do everything for all of the users (add, modify, remove).
  • %
    • Administrator permission value, allows to do everything.
There are also some other cases like "%.1" or "%.update.1", but those permission values makes no logical sense and should never be used.

REST API endpoints

For each of the new action files, an API endpoint was created in order to be able to call the actions from the website. Here is the list of the endpoints for each file, the parameter(s) they are able to manage and the permission you need to use it.

/!\ You won't be able to get anything from the endpoints if you don't have a user with the permissions. What you need to do is to create a user (with your username/mail), make a group for him and set the permissions for the group (don't forget to link the group and the user).

Permissions

In the below list, parameters marked with the * sign are mandatory, others are optional. All of the parameters of this list can be sent using the GET or the POST system (parameters in the url or in the data). However the HTTP method that needs to be used to make the call is also specified by endpoint (usually GET for views and POST for the rest).

  • ListPermissionsAction.py
    • Endpoint: permissions
    • HTTP method : GET
    • Parameter : groupId, userId, groupName, userName
    • Permission : permission.view
This endpoint is used to create the view that lists all of the permissions in the database. You can use the parameters to get the permissions either by group or by user. Parameters are taken in order groupId>userId>groupName>userName and only the first one which is filled will be used.

  • AddPermissionAction.py
    • Endpoint : addpermission
    • HTTP method : POST
    • Parameters : groupId*, permissionValue*
    • Permission : permission.add
This endpoint adds permission to the database. To do so, you need to specify the ID of the group for which you want to add permission and the string value of the permission you want to give.

  • RemovePermissionAction.py
    • Endpoint : removepermission
    • HTTP method : POST
    • Parameter : permissionId*
    • Permission : permission.remove.<permissionId>
This one removes permission from the database, the parameter you have to fill is the ID of the permission that you want to remove.

Users

  • ListUsersAction.py
    • Endpoint : users
    • HTTP method : GET
    • Parameter : groupId, groupName
    • Permission : user.view
This endpoint lists the users of the database. You can add the groupId or groupName parameter if you want to have only the users of one group.

  • AddUserAction.py
    • Endpoint : adduser
    • HTTP method : POST
    • Parameters : userName*, userDN, email
    • Permission : user.add
This action adds a user in the database. To add a user, you need to give at least the userName parameter. The userDN parameter will be used for people using certificate to authenticate, and the email will be used for the people using the Single Sign-On.

  • RemoveUserAction.py
    • Endpoint : removeuser
    • HTTP method : POST
    • Parameter : userId*
    • Permission : user.remove.<userId>
This action allows us to remove the user with the given userId from the database.

  • UpdateUserAction.py
    • Endpoint : updateuser
    • HTTP method : POST
    • Parameter : userId*, userName, userDN, email
    • Permission : user.update.<userId>
This action is used to update user’s information. The parameter userId is mandatory to know which user will be updated, the other one’s are optional. However you need to fill at least one, otherwise it makes no sense to make a call on this endpoint, and if none of the optional parameters are set, an exception will be thrown.

Groups

  • ListGroupsAction.py
    • Endpoint : groups
    • HTTP method : GET
    • Parameter : userId, userName
    • Permission : group.view
This endpoint allows us to list the groups of the database. If the userId or the userName parameter is filled, the method will only retrieve the groups for which this user is part of.

  • AddGroupAction.py
    • Endpoint : addgroup
    • HTTP method : POST
    • Parameters : groupName*, egroupName
    • Permission : group.add
This action adds a group in the database. You have to give at least the groupName to be able to create one group.

  • RemoveGroupAction.py
    • Endpoint : removegroup
    • HTTP method : POST
    • Parameter : groupId*
    • Permission : group.remove.<groupId>
This method removes the given group from the database using the groupId.

  • UpdateGroupAction.py
    • Endpoint : updategroup
    • HTTP method : POST
    • Parameters : groupId*, groupName, egroupName
    • Permission : group.update.<groupId>
This action is used to update group’s information. The mandatory parameter is the groupId to know which group will get an update, the other one’s are optional. However you need to fill at least one, otherwise it makes no sense to make a call on this endpoint, and if none of the optional parameters are set, an exception will be thrown.

Link user and group

  • AddUserGroupAction.py
    • Endpoint : addusergroup
    • HTTP method : POST
    • Parameters : userId*, groupId*
    • Permission : group.update.<groupId> and user.update.<userId>
This endpoint allows us to put a user in a group.

  • RemoveUserGroupAction.py
    • Endpoint : removeusergroup
    • HTTP method : POST
    • Parameters : userId*, groupId*
    • Permission : user.update.<userId> and group.update.<groupId>
This endpoint allows us to remove a user from a group.

Graphical interface presentation

In this chapter, I will make a quick presentation of the interface of my module.

This interface is quite simple, you can see the full user list at the top of the page. The column “User Name”, “User DN” and “Email” are editable, and after modification, you can use the update button to push the modifications to the database.

In the “Add user” form, you can add a user to the database. You need to set at least the user name field in order to make it work. The email field is using the “type=’email’” attribute, however since the button “Add User” is not of type “submit”, the colour will turn red if an invalid email is given, but you will still be able to add it as it is.

The “User/group link” form is used to manage the links between users and groups, both of the fields must be filled to make it work either way.

This page is very similar to the user’s one. The editable fields are “Group Name” and “Group E-name”. In the “Add Group” form you need to fill at least the group name field, and in the “User/group link” form you need to fill both fields.

This part of the interface is smaller than the other ones, since there is no valid reason to update the value of permission, you are only able to remove and add some.

Error management

Each time a problem occurs (exceptions from oracle or empty fields for instance) a “DashboardException” is raised. The exception itself is raised with an information message that can be shown to the user to tell him what exactly happened.

Standard developer usage

To use the methods from the AuthoriseDAO, you have to follow those steps:

  1. Make your DAO class inherit from the OracleAuthoriseDAO
  2. Make your action class inherit from the AuthoriseAction class (this class itself inherits from Action)
    1. This step allows you to use the getCurrentUser() method.
    2. Use the below pattern

HasPerm decorator

To make the life of the developers easier, a decorator was created that we can use in some cases. To use it, what you have to do is to import the “HasPerm” class in the actions file you want to and you can then decorate your “perform” methods like this:

Now keep in mind that you can only use it if you don’t need to create a permission value using some of the parameters given in the request. For instance, you can’t use it in the remove actions, because you will need to create a permission value that looks like “admin.remove.123” and the “123” is the ID of the admin. Here is the decorator implementation:

-- NguyenPhuongLe - 2015-07-24

Edit | Attach | Watch | Print version | History: r7 < r6 < r5 < r4 < r3 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r7 - 2015-07-30 - unknown
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    ArdaGrid All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright &© 2008-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback