OAuth2/OIDC AAI support in DIRAC #5045
This implementation able to test on development server.
Andrii Lytovchenko, CPPM
CONTENT
INTRODUCTION
DIRAC is using only X509 certificates for user authentication, but using X509 certificates is complicated for the end-users:
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
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.
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:
The authentication code grant type is used by clients to exchange an authorization code for an access token on the server-side.
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
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
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
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.
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
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
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:
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
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
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..
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.
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.
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>
}
REALIZATION
To get a proxy through OAuth2 authorization, use the dirac-proxy-init command with special switches:
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.
TODO
Thanks for attention!