Authentication and Authorization
This section describes the underlying concepts of the SIP authentication and authorization services.
Motivation
User authentication and authorization is a topic that comes up in almost every application. It is a very sensitive topic and there is a lot of potential to do things the wrong way. That's why the SIP provides a centralized authentication and authorization solution that application can and should use instead of implementing their own solutions.
Authentication vs Authorization
It's really important to be aware of the difference between authentication and authorization:
- Authentication: Authentication, e.g. authenticating a client (for example a user) against an application, means verifying that the client identity. In general this is done by a secret that is defined by the client (for example a password) which he has to enter and is then checked against an internal database.
- Authorization: Authorization, e.g. authorizing of a client to access a specific resource, means deciding whether the (authenticated) client is allowed to access a resource or perform a certain action on it.
This can be further illustrated with a simple real-world example: If you visit a foreign country and have to go through passport-control, then the friendly passport officer will most likely perform these two steps:
- Check whether your passport or ID card is valid, for example by examining certain watermarks on the paper or checking the passport number against a database. This way the passport officer has authenticated you.
- Secondly the officer will check whether you, as a person, are allowed to enter the country, for example by checking whether your name is on a list of people who are not allowed to enter the country. This way the officer authorizes you to enter the country (access the resource).
Although this concept is not that difficult to understand there is still a lot of confusion around them and a lot of online resource or programs use the terms interchangeably, which is really wrong. In this documentation we will try to make the difference very clear. Also we use the Term Auth to refer to both authentication and authorization together.
High-Level
This page gives a high level description of how authentication and authorization works using the OAuth 2.0 and OpenID Connect protocol (which are used on the SIP).
There are different processes explained in this documentation:
- User granting authorization (OAuth 2.0)
- User authentication (OIDC)
- Authorizing Users (Role based authorization / Resource based authorization)
which together form the basis for authentication and authorization on the SIP. Depending on your application you will need to use only a selection of the processes or all of them.
User granting authorization (OAuth 2.0)
If you have ever connected third-party application to your Facebook (for example to allow them to post your newest high-score on candy crush on your timeline) or Google (for example to automatically add some work-out hours to your Google calendar, which in the end of course you did not do, but still made you feel good), then you have already used the OAuth 2.0 protocol.
OAuth 2.0 was designed to allow users to selectively delegate the access and privileges they have to applications that do something with the given permissions.
How OAuth 2.0 works
OAuth 2.0 defines four roles (the description are taken from the OAuth 2.0 specification):
- resource owner: An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
- resource server: The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
- client: An application making protected resource requests on behalf of the resource owner and with its authorization. The term "client" does not imply any particular implementation characteristics (e.g., whether the application executes on a server, a desktop, or other devices).
- authorization server: The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.
The following example should illustrate how OAuth 2.0 works:
An end-user (resource owner) can grant a fictional application (client) that can be used to add a license to all Github projects stored on Github (resource server) under her name without sharing her username and password with the fictional application. Instead the fictional application (client) will redirect the user to the GitHub Login page (authorization server) which asks the user (after she has logged in) to grant the needed access rights to the application. If the access is granted GitHub will issue specific credentials (access token) to perform this action. The fictional application can then use this access token to access the GitHub API (resource server) to perform the desired action.
Please note that:
- the process of authenticating the user is not part of the OAuth 2.0 protocol.
- OAuth 2.0 is only used to give the application the necessary privileges - OAuth 2.0 does not check at any time if the user is allowed to call this function/action, your application is responsible for taking care of that.
User authentication (OpendID connect)
The process of user authentication is the process of authentication a user, e.g. checking that the user actually is who he says. VSETH uses the SWITCH AAI service to authentication users because most of our users already have a SWITCH login since they are members of ETH Zurich or another Swiss university. As a developer however you don't have to deal with using the SWITCH service directly. Instead you can use the central auth server of SIP, which provides authentication services using the OpendID Connect protocol.
How OpenID Connect (OIDC) works
The OIDC protocol is an extension of the OAuth 2.0 protocol which adds authentication to the protocol (remember that the OAuth 2.0 protocol is only design as an authorization framework but not as a authentication protocol). Being an extension of the OAuth2 protocol it works more or less the same as the OAuth 2.0 with two additions:
- The introduction of an ID Token, which identifies users and can therefore be used for user authentication by the client.
- The introduction of a special
/userinfo
endpoint that applications can use to access information about the authenticated user.
How to add authorization
In contrast to the above mentioned example we want to extend the above mentioned features in VSETH: Every user in VSETH has a certain amount of rights, so there are also actions that a user is not allowed to perform. In addition, we have the restriction that an application should only be allowed to request certain rights. This makes it possible, for example, that there are applications that can find out e-mail addresses of nethz users, but at no time can see their gender or home address. This is a very good idea from a privacy point of view, but these features are not foreseen in pure OAuth 2.0. Larger companies grant privileges based on roles: With the OAuth token, the application retrieves a UserInfo endpoint in which the roles of the authenticated user are noted and then decides whether the user is authorized to perform the desired action. This method is preferable when all applications that can request tokens are completely under the control of the organization. Each application could take a user's token and call a highly privileged endpoint: Since no one controls whether this application is allowed to do so, an "evil" application can perform all actions that the user is allowed to perform. In VSETH, the assumption is that students can simply connect applications they have programmed to Keycloak (and thus OAuth), so it would make sense to assign rights again for each application.
Keycloak itself knows authorization on a user level, but this is orthogonal to the previously described authorization on application level. In order to overcome these limitations, we have considered the following concept.
Scope Model
Let's take an example: As API we take the "People-API", which can find out and return any arbitrary pieces of information about people. One of them is the image of the other users. Since not every user of the People API is allowed to see images of other people, the right to request images should only be given to certain users. The "Personenorakel" is a simple web application that provides a graphical interface to the People API (and is allowed to request images from users). In addition, there is an application that lists the nethz abbreviations of the current VSETH board, for which it also needs the People API, let's call it "Board Application". It should be possible for people to list pictures in the Personenorakel, but the board application should not be able to do this in order to best protect personal information ("defense-in-depth"). In our modelling we map these access rights as follows:
There is the People-API-Picture role, to which all users who are allowed to see images in the People-API are assigned.
There is the (global) OAuth 2.0 People-API-Picture scope, which can be requested by all applications that want to request images. This scope may only be requested by the Personenorakel, but not by the board application.
The People API has a People-API-Picture resource that symbolizes the images in the People API.
The People API has set a policy that verifies the following. If an application with a token wants to request a user's image (i.e. the People-API-Picture resource), the following conditions must be met:
- The token must have the People-API-Picture scope.
- The user must include the People-API-Picture role.
This ensures that both the user and the token are authorized to request images from the People API. Since the manual creation of all required parts is very laborious, it should be handled by Gatekeeper.