metadatamanagement icon indicating copy to clipboard operation
metadatamanagement copied to clipboard

Backend: Use DLP as OpenID Connect Provider

Open rreitmann opened this issue 3 years ago • 4 comments

  • Security Utils must use OpenIdContext
  • usermanagement must be removed
  • UserRepository queries must use the DLP User API
  • check if storing on behalf is still possible
  • projectmanagement: query users by login and email and role, and assign to project group (exclude already assigned ones)
  • roles must be mapped from scopes

rreitmann avatar Sep 30 '21 10:09 rreitmann

DLP User API must provide the following methods:

  /** Get a list of all users having the specified role. Used to send email to all users havin a role. */
  List<User> findAllByAuthoritiesContaining(Authority authority);
  /** Get a list of all users where login or email adress starts with the given strings. Used to assign users to projects. */
  List<User> findAllByLoginLikeOrEmailLike(String login, String email);
  /** Get a list of all users for the given logins. Used to send emails to project members */
  List<User> findAllByLoginIn(Set<String> userLoginNames);
  /** Get user details by given login or given email. Used to present details to the user. Might be obsolete. */
  Optional<User> findOneByLoginOrEmail(String login, String email);
  /** Get user by given login. Used to send email when a task of a user completed for example. */
  Optional<User> findOneByLogin(String login);

Additionally we need to be able to save a user field like welcomeDialogDeactivated.

rreitmann avatar Sep 30 '21 11:09 rreitmann

/** Get a list of all users having the specified role. Used to send email to all users havin a role. */
  List<User> findAllByAuthoritiesContaining(Authority authority);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?include=roles&filter%5Broles.id%5D=role_publisher' \
  --header 'Authorization: Basic ****
/** Get a list of all users where login or email adress starts with the given strings. Used to assign users to projects. */
  List<User> findAllByLoginLikeOrEmailLike(String login, String email);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?include=roles&filter%5Bor-group%5D%5Bgroup%5D%5Bconjunction%5D=OR&filter%5Bname-00-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-00-filter%5D%5Bcondition%5D%5Boperator%5D=STARTS_WITH&filter%5Bname-00-filter%5D%5Bcondition%5D%5Bvalue%5D=r&filter%5Bname-00-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Bpath%5D=mail&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Boperator%5D=STARTS_WITH&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Bvalue%5D=r&filter%5Bmail-00-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group' \
  --header 'Authorization: Basic ****
/** Get a list of all users for the given logins. Used to send emails to project members */
  List<User> findAllByLoginIn(Set<String> userLoginNames);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=rreitmann&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D%5B2%5D=adaniel&include=roles' \
  --header 'Authorization: Basic *****
/** Get user details by given login or given email. Used to present details to the user. Might be obsolete. */
  Optional<User> findOneByLoginOrEmail(String login, String email);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bor-group%5D%5Bgroup%5D%5Bconjunction%5D=OR&filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D=rreitmann&filter%5Bname-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group&filter%5Bmail-filter%5D%5Bcondition%5D%5Bpath%5D=mail&filter%5Bmail-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bmail-filter%5D%5Bcondition%5D%5Bvalue%5D=reitmann%40dzhw.eu&filter%5Bmail-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group' \
  --header 'Authorization: Basic *****
  /** Get user by given login. Used to send email when a task of a user completed for example. */
  Optional<User> findOneByLogin(String login);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D=rreitmann&include=roles' \
  --header 'Authorization: *****

rreitmann avatar Oct 06 '21 12:10 rreitmann

For saving a field like welcome_dialog_deactivated we neeed to allow jsonApi to update users: http://localhost:8082/admin/config/services/jsonapi

Additionally we need to add the field to the account and hide it from displaying: http://localhost:8082/admin/config/people/accounts/fields http://localhost:8082/admin/config/people/accounts/form-display http://localhost:8082/admin/config/people/accounts/display

Then you can update a user with PATCH:

curl --request PATCH \
  --url http://localhost:8082/jsonapi/user/user/12170c0d-853b-4a8c-9780-873b10da4562 \
  --header 'Authorization: Basic *****' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
  "data": {
    "type": "user--user",
    "id": "12170c0d-853b-4a8c-9780-873b10da4562",
    "attributes": {
        "field_welcome_dialog_deactivated": false
    }
  }
}'

rreitmann avatar Oct 07 '21 07:10 rreitmann

There is a Pull Request for this: https://github.com/dzhw/metadatamanagement/pull/3037

We have setup an additional branch sso-workaround which disables JWT Validation due to an issue in the identity provider image (see below).

The following topics are open:

  • test on the dev-system and on the test-system
  • user migration (dev, test -> DLP-Stage, prod -> DLP he)
  • aws fargate task/container configuration has not been set so far

Documentation can be found here: https://github.com/dzhw/metadatamanagement/wiki/Drupal-Identity-Provider-Overview-and-Setup

There are currently the following issues with the identity provider image (https://hub.docker.com/r/sanduhrs/identity-provider), which have been reported to the DLP maintainers:

  1. issuerUri im Access-Token enthält trailing Forward-Slash (e.g. "http://localhost:8082/"), wodurch Token-Validierung fehlschlägt <- im branch sso-workaround ist die Token-Validierung aus diesem Grund gerade ausgebaut
  2. Access-Token enthält user-id anstatt username/loginname => usernames sollen unveränderlich sein <- als workaround lokal kann man in den SecurityUtils die user-id auf den username mappen:
   public static String getCurrentUserLogin() {
     var authentication = SecurityContextHolder.getContext().getAuthentication();
 
+    if (authentication != null && authentication.getName().equals("1")) {
+      return "rreitmann";
+    } else if (authentication != null && authentication.getName().equals("4")) {
+      return "dataprovider";
+    }
     return authentication != null ? authentication.getName() : null;
   }

  1. welcome_dialog_deactivated wird nicht mit ID-Token ausgeliefert
  2. Anonymous Zugriff zu JSONAPI ist möglich (i.e. man kann alle Userdaten lesen wenn man kein Filter benutzt)
  3. JSON:API Setting "Allowed Operations" sollte von Anfang an "Accept all JSON:API create, read, update, and delete operations" sein.

Ideally the identity provider image would be fully configured with all roles, languages and oauth2 clients.

rreitmann avatar Dec 20 '21 11:12 rreitmann