magda-io / magda

A federated, open-source data catalog for all your big data and small data
https://magda.io
Apache License 2.0
508 stars 93 forks source link

Login stage needs to save user's esri groups in the session #2437

Closed mwu2018 closed 5 years ago

mwu2018 commented 5 years ago

After a user is authenticated by Esri portal, magda needs to use the access token to query Esri on user's groups and save the groups in the current session.

Magda authz will use the groups info to query OPA. Details follow.

  1. At login, get the list of groups that user belongs to
  2. Save this info to session
  3. When auth-api proxy opa request, make sure the input.user.groups object contains this info from session (Currently, auth-api will auto re-create input.user only from session)

It needs to be saved in the passport js session (https://www.airpair.com/express/posts/expressjs-and-passportjs-sessions-deep-dive) then put into the JWT token somehow so that the auth API can pull it out.

t83714 commented 5 years ago

More details on this:

1> All session data is currently saved in session table (session db) in simple JSON format. Here is a sample:

{
  "cookie": {
    "originalMaxAge": 25200000,
    "expires": "2019-08-29T06:56:56.103Z",
    "httpOnly": true,
    "path": "/"
  },
  "passport": {
    "user": {
      "id": "c517c09a-4c2a-4611-9add-3a5a4d236f19"
    }
  }
}

2> You can tell from the sample data above that we currently only save user id to session via passport lib:

"user": {
      "id": "c517c09a-4c2a-4611-9add-3a5a4d236f19"
    }

It's been done in every Madga oAuth2 module/plugin (in magda-gateway/src/oauth2) by calling createOrGetUserToken (in magda-gateway/src/createOrGetUserToken.ts):

https://github.com/magda-io/magda/blob/bbbc5ecec081cf5e76fb2d5f4bb4e692c27f2296/magda-gateway/src/createOrGetUserToken.ts#L8-L22

The actual user object that is saved to session table is created here:

https://github.com/magda-io/magda/blob/bbbc5ecec081cf5e76fb2d5f4bb4e692c27f2296/magda-gateway/src/createOrGetUserToken.ts#L42-L46

You actually can simply add a new key to add extra data to the session user object.

3> However, we'd better not modify createOrGetUserToken.ts to add the retrieve user group from ESRI server logic.

Instead, we can put that logic in DT ESRI oAuth plugin so that it won't impact other oAuth2 plugins.

e.g. we decide to use magda-gateway/src/oauth2/arcgis.ts, we can add the logic around the following lines:

https://github.com/magda-io/magda/blob/bbbc5ecec081cf5e76fb2d5f4bb4e692c27f2296/magda-gateway/src/oauth2/arcgis.ts#L80-L82

the userId variable above is actually a user object in the structure of:

 {
      "id": "c517c09a-4c2a-4611-9add-3a5a4d236f19"
    }

We can create a new key before call cb() in order to have it saved in session db.

4> We can add group info to JWT token as well. But in order to make JWT token not too big (could also be more generic for other use cases), another way to do it could be (@AlexGilleran Please comment on this one):

4.1> Encode the session id to JWT token as well (we currently only encode user_id) around there:

https://github.com/magda-io/magda/blob/bbbc5ecec081cf5e76fb2d5f4bb4e692c27f2296/magda-gateway/src/createApiRouter.ts#L36-L43

The session id can be simply retrieved from req.sessionID . see here

4.2> When proxy OPA request, Auth-API appends user info at here:

https://github.com/magda-io/magda/blob/bbbc5ecec081cf5e76fb2d5f4bb4e692c27f2296/magda-authorization-api/src/createOpaRouter.ts#L118-L121

It simply decodes the JWT token, gets the user_id and re-creates user data from DB.

One simple solution here could be:

We can: