1 of 21

OAuth2/OIDC AAI support in DIRAC #5045

This implementation able to test on development server.

Andrii Lytovchenko, CPPM

2 of 21

CONTENT

  • Introduction
    • Prerequisite
    • Basic concepts
    • The main goal
  • New things
    • Identity/Proxy Providers
    • Authorization sessions
    • Dynamic Registry
    • REST APIs
  • Implementation
    • Caching dynamic information
    • Authorization with users IDs from IdP
    • UserName/group as unique user identifier
    • Group status
    • dirac-proxy-init with OAuth2
  • Realization
  • Compatibility
  • TODO

3 of 21

INTRODUCTION

DIRAC is using only X509 certificates for user authentication, but using X509 certificates is complicated for the end-users:

  • Complex issuing procedure, yearly renewal, installation in multiple places with a format conversion, loading in browsers, etc
  • Users of many communities do not have access to Certification Authorities issuing X509 certificates

NOTE: still need to be sure that the certificate is uploaded to the ProxyManager(unless it can be accessed through a DIRAC-registered proxy provider), because it is used in DISET.

Single sign-on (SSO) is an authentication process that allows a user to access multiple applications with one set of login credentials.

The EGI Check-in service enables access to EGI services and resources using federated authentication mechanisms

4 of 21

INTRODUCTION

OAuth 2.0 is the industry-standard delegation protocol for conveying authorization decisions across a network of web-enabled applications and APIs, full specification - RFC6749. More information here.

Open ID Connect is an interoperable authentication protocol based on the OAuth 2.0 family of specifications. More information here.

OAuth2 roles:

Resource owner is the user who is giving access to some portion of their account.

Resource server is the server that contains the user’s information that is being accessed by the third-party application, capable of accepting and responding to protected resource requests using access tokens.

Authorization server is the server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

Client is the app that is attempting to act on the user’s behalf or access the user’s resources.

5 of 21

INTRODUCTION

An authorization grant is a credential representing the resource owner's authorization (to access its protected resources) used by the client to obtain an access token

OAuth2 provide a four main authorization grant types:

  • authorization code,
  • implicit,
  • resource owner password credentials,
  • client credentials.

The authentication code grant type is used by clients to exchange an authorization code for an access token on the server-side.

6 of 21

INTRODUCTION

The main goal to introduce the AuthN/AuthZ mechanism to DIRAC based on the use of Identity Provider services using OIDC(OAuth2) protocol and authorization code grant type.

TornadoServer + SessionManager

http services

REST endpoints

Proxy Endpoint

Auth Endpoint with authlib server

client

Identity Provider

old good DISET

dips services

Web handlers

authentication request

tokens

get proxy request

proxy

7 of 21

INTRODUCTION

The main goal to introduce the AuthN/AuthZ mechanism to DIRAC based on the use of Identity Provider services using OIDC(OAuth2) protocol and authorization code grant type.

in tread: waiting of end authorization..

Auth REST API

GET /auth/<IdP>?<options>

Create/cache a authentication session

  • Get full user profile, tokens
  • Cache it & store to DB

URL for authN

AuthManager service

Submit URL to browser

and authN

IdP endpoint

server side authN code flow

GET /proxy?<options>

Proxy REST API

AuthZ with ID from IdProvider

AuthManager

Get proxy from DB or generate it

ProxyManager service

return proxy

If AuthN is successful, the DIRAC tokens will be passed

If the proxy is received, we can continue with DISET or http..

and may do request a proxy..

Generate DIRAC tokens

8 of 21

NEW THINGS

Identity Provider (IdP) is a service that creates, maintains and manages user identity information and provides it together with the user authentication.

Proxy Provider (PrP) is a service that creates, maintains, and manages X509 certificate proxies and provides them together with the user authentication.

9 of 21

NEW THINGS

An authorization session via DIRAC with OAuth2 is short-lived (and long-lived if used via WebApp) cached data with a unique session name. During this session, tokens received from IdP are stored in the database/cache. Based on the received user information, DIRAC tokens are created, which the client receives and with the help of which it can make authorized requests to the DIRAC server part.

For a better understanding let's draw an analogy:

certificate authority

identity provider

proxy

DN

ID

DIRAC group as proxy extension

DIRAC group as token scope

access token

certificate

refresh token

10 of 21

NEW THINGS

With this modification DIRAC CS configuration remains a priority source! But there will be new opportunities. User/Group/VO mapping can be done based on the cached IdP and VOMS users information which is updated regularly and is used by the dynamic Registry. The DIRAC code everywhere was aligned with this modification.

CS(minimal configuration with using cache)

Registry

Users� username� ID = <IdP ID>

Groups� user_group� Properties = NormalUser� VOMSRole = /somevo

VO� somevo� VOMSName = somevo� VOAdmin = adminuser

IdP cache

ID/DN/VO/Role

VOMS cache

DN/VOMSRole/status

Registry

DNs

username

groups

groups

DNs

getDNsForUsername

getUsernameForDN

getGroupsForUser

getGroupsForDN

getDNsInGroup

11 of 21

NEW THINGS

To provide authentication flow using the OAuth2 has been provided REST APIs for some services, moved from RESTDIRAC.

TornadoServer has been slightly modified to use it for WebApp and REST APIs:

  • HandlerManager modified to collects also endpoints and portal handlers
  • TornadoService was divided into TornadoREST for the REST handlers and a BaseRequestHandler class containing the main code for TornadoREST and TornadoService
  • has been added authentication with OAuth tokens

12 of 21

IMPLEMENTATION

When using external IdPs, each successful user authentication provides also the user profile information that should be updated on the DIRAC side. This information is stored in the corresponding caches(IdP and VOMS). The Registry becomes dynamic because it uses the cached information. The user’s information from VOMS services is also dynamically cached.

Registry

IdPs cache:

<ID>: {

Providers: [ <IdPs> ],

<provider>: [ <session dict> ],

DNs: [ <DN dict> ]

}

update user profile from IdP

AuthManagerData

update

cache on

client side

IdPs cache

AuthManagerService

VOMS cache:

<VOMS VO>: {

<DN>: {

VOMSRoles: [ <roles> ],

suspendedRoles: [ <roles> ], .. }

}

ProxyManagerData

VOMS cache

ProxyManagerService

update VOMS info from VOMS API

import

backup cache to work directory as files

13 of 21

IMPLEMENTATION

IMPORTANT: certificate DN's are no more the primary user identifiers. We have to provide a possibility also to authorize users that come with ID from IdP instead of certificate/DN. When a user authenticates through an IdP and made request to DIRAC, he can be authorized with his IdP ID, by matching it with IDs registered in CS. DISET has also been slightly modified, adding the ability to transmit ID of authorization session.

Registry

AuthManager

http: ID (or DN), Group(optional)

ssl: DN, Group(optional)

Forwarding credentials

AuthZ DIRAC user by ID/DN

Initialize DIRAC group

CS + cache

CS + cache

if group attached

- check attached group

if no group attached

- check all user groups

- attach first in the list

- find DN for user/group

- get properties for group

Access check

14 of 21

IMPLEMENTATION

User IDs now come from various identity providers. Within DIRAC, username becomes the main, single and unique user identifier independent from various user identities from different providers. As a consequence, all the CS options with user identities as values, e.g. pilot user, request owner, etc, should be expressed in terms of user names rather than DNs.

For backward compatibility current options in a form of DN are still accepted but should be replaced eventually.

For example, ProxyManager API was modified to use username or DN and the code everywhere (Shifter, DiracAdmin, etc.) was aligned with that.

def userHasProxy(self, userDN, userGroup, validSeconds=0):

def downloadProxy(self, userDN, userGroup, limited=False..

def userHasProxy(self, user, group, validSeconds=0):

def downloadProxy(self, user, group, limited=False..

15 of 21

IMPLEMENTATION

One more thing is a possibility to check the actual status for user group. Group access status for the given user depend on Suspended status in VOMS, expired status of tokens or uploaded certificates, etc.

16 of 21

IMPLEMENTATION

For authentication in the DIRAC client CLI, the dirac-proxy-init script was modified by adding logic to make http requests to the DIRAC REST APIs of AuthManager and ProxyManager services to authorize and get proxy. Also added a few nice things.

waiting process...

Class halo contain spinners that used to show waiting process.

Method qrterminal adds possibility to show some information as QRCode, but to use it need to add pyqrcode package to DIRACOS.

17 of 21

REALIZATION

To start using the new functionality one needs to install the AuthManager and ProxyManager services, as well as the AuthDB and ProxyDB databases (note that the structure of the ProxyDB has changed a bit), use the scripts in /Core/Tornado/scripts to run the REST points: AuthHandler, ProxyHandler and ConfHandler.

After that register DIRAC as client in IdP and configure IdP in the CS /Resources/IdProviders section.

dirac.cfg

Resources {

IdProviders {

<IdP name> {

ProviderType = OAuth2

issuer = https://…

client_id = <received ID>

client_secret = <received key>

}

18 of 21

REALIZATION

To get a proxy through OAuth2 authorization, use the dirac-proxy-init command with special switches:

19 of 21

COMPATIBILITY

Although this PR introduces new functionalities, the current mechanisms of X509 based user authentication are still maintained. Installations and users using old good X509 certificates will continue to work without any changes.

The Registry after the modification will still use the information from the CS service with highest priority and will not crash in case the AuthManager service is down, it will try to connect and will ignore service by minute.

There are many files affected by the PR changes but these little modifications should not have changed the main logic of these services.

20 of 21

TODO

  • Fix/add the tests
  • Complete documentation
  • Add packages to DIRACOS:
    • pyqrcode to use QRCode in terminal
    • termcolor to realize spinners
    • authlib==0.15.3 for authentication server
  • Test and fix bugs related to changes, rebase with the latest release, etc.

21 of 21

Thanks for attention!