Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9229 - Add bearer token auth mechanism for OIDC user with feature flag #9591

Merged
merged 7 commits into from
May 18, 2023

Conversation

johannes-darms
Copy link
Contributor

@johannes-darms johannes-darms commented May 15, 2023

@pdurbin pdurbin added this to Ready for Review ⏩ in IQSS/dataverse (TO BE RETIRED / DELETED in favor of project 34) via automation May 15, 2023
@pdurbin pdurbin self-assigned this May 15, 2023
@pdurbin pdurbin added Feature: Account & User Info Size: 3 A percentage of a sprint. 2.1 hours. labels May 15, 2023
@pdurbin pdurbin moved this from Ready for Review ⏩ to In Review 🔎 in IQSS/dataverse (TO BE RETIRED / DELETED in favor of project 34) May 15, 2023
@coveralls
Copy link

coveralls commented May 16, 2023

Coverage Status

Coverage: 20.261% (+0.05%) from 20.214% when pulling 9c7fe07 on johannes-darms:9229-2-bearer-token into fc23042 on IQSS:develop.

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the previous iteration of this pull request (#9532) and it worked so I'm approving this.

It looks like @johannes-darms incorporated all of my suggestions (thanks!).

@kcondon please note that the previous PR has all the details on how to test. I did my testing with Docker. I'm happy to walk your through what I did.

IQSS/dataverse (TO BE RETIRED / DELETED in favor of project 34) automation moved this from In Review 🔎 to Ready for QA ⏩ May 16, 2023
@pdurbin pdurbin removed their assignment May 16, 2023
@kcondon kcondon self-assigned this May 16, 2023
Copy link
Contributor

@poikilotherm poikilotherm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry to be pedantic, but I do see some places that IMHO could result in a bad API user experience. Thanks for keeping up the good work.

@@ -2391,6 +2404,9 @@ please find all known feature flags below. Any of these flags can be activated u
* - api-session-auth
- Enables API authentication via session cookie (JSESSIONID). **Caution: Enabling this feature flag exposes the installation to CSRF risks!** We expect this feature flag to be temporary (only used by frontend developers, see `#9063 <https://github.com/IQSS/dataverse/issues/9063>`_) and removed once support for bearer tokens has been implemented (see `#9229 <https://github.com/IQSS/dataverse/issues/9229>`_).
- ``Off``
* - api-bearer-auth
- Enables API authentication via Bearer Token for OIDC User Accounts. **Information: This feature works only for OIDC UserAccounts!**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Enables API authentication via Bearer Token for OIDC User Accounts. **Information: This feature works only for OIDC UserAccounts!**
- Enables API authentication via Bearer Token for OIDC User Accounts. **Note: This feature works only when using an :doc:`OpenID Connect authentication provider <oidc>`!**

Comment on lines +333 to +345
.. _bearer-token-auth:

Bearer Token Authentication
---------------------------

Bearer tokens are defined in `RFC 6750`_ and can be used as an alternative to API tokens. This is an experimental feature hidden behind a feature flag.

.. _RFC 6750: https://tools.ietf.org/html/rfc6750

To enable bearer tokens, you must install and configure Keycloak (for now, see :ref:`oidc-dev` in the Developer Guide) and enable ``api-bearer-auth`` under :ref:`feature-flags`.

You can test that bearer tokens are working by following the example under :ref:`bearer-tokens` in the API Guide.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do understand this is explained in the API docs (perfect place), this repetition and elaboration here seems somewhat misplaced IMHO. Shouldn't we keep this in the API guide?

@@ -12,6 +12,7 @@ services:
- DATAVERSE_DB_HOST=postgres
- DATAVERSE_DB_PASSWORD=secret
- DATAVERSE_DB_USER=${DATAVERSE_DB_USER}
- DATAVERSE_FEATURE_API_BEARER_AUTH=1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not have this feature on by default. I'd rather keep this file less feature enabled, but more bare-bones.

Comment on lines +102 to +120
dev_keycloak:
container_name: "dev_keycloack"
image: 'quay.io/keycloak/keycloak:19.0'
hostname: keycloak
environment:
- KEYCLOAK_ADMIN=kcadmin
- KEYCLOAK_ADMIN_PASSWORD=kcpassword
- KEYCLOAK_LOGLEVEL=DEBUG
- KC_HOSTNAME_STRICT=false
networks:
dataverse:
aliases:
- keycloak.mydomain.com #create a DNS alias within the network (add the same alias to your /etc/hosts to get a working OIDC flow)
command: start-dev --import-realm --http-port=8090 # change port to 8090, so within the network and external the same port is used
ports:
- "8090:8090"
volumes:
- './conf/keycloak/oidc-realm.json:/opt/keycloak/data/import/oidc-realm.json'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note:

  1. Keycloak 19 is outdated.
  2. I dislike adding more containers than necessary here. This is an experimental feature and right now, for most of development this is waste of CPU cycles. Can we make this scale: $ENABLE_KEYCLOAK, have ENABLE_KEYCLOAK=0 in .env so you need to enable this by adding ENABLE_KEYCLOAK=1 when starting this?

@Inject
protected UserServiceBean userSvc;
private static final Logger logger = Logger.getLogger(BearerTokenAuthMechanism.class.getCanonicalName());
@Override
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Override
@Override

/**
* Enables API authentication via Bearer Token.
* @apiNote Raise flag by setting "dataverse.feature.api-bearer-auth"
* @since Dataverse @TODO:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO. Maybe fine to put 5.14 here, I have a feeling this might make it.

Comment on lines +42 to +43
sut.authSvc = Mockito.mock(AuthenticationServiceBean.class);
sut.userSvc = Mockito.mock(UserServiceBean.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these into setUp() to make the tests more readable. (Goes as well for all the other occurences...)

}

@Test
@JvmSetting(key = JvmSettings.FEATURE_FLAG, value = "true", varArgs = "api-bearer-auth")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry that this is a bit messy - I did not yet implement setting something like this on a class level, this needs tuning. (Would avoid the repetition)

return null;
}
}
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not covered by a test, but is part of the API contract. Please make sure there is a unit test for this.

Comment on lines +282 to +283
* @throws IOException
* @throws OAuth2Exception
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When are these exceptions thrown?

@pdurbin
Copy link
Member

pdurbin commented May 17, 2023

@poikilotherm I'm not sure if this was your intention by selecting "request changes" but merging is blocked until you switch to "comment" or "approve".

Co-authored-by: Oliver Bertuch <poikilotherm@users.noreply.github.com>
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@poikilotherm and I chatted about this PR and left some comment.

return userInfo.get();
}
} catch ( IOException| OAuth2Exception e) {
logger.log(Level.FINE, "Bearer token detected, provider " + provider.getId() + " indicates an invalid Token, skipping", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like the 401 is sent later because we aren't doing anything in the catch here.

* @throws IOException
* @throws OAuth2Exception
*/
public Optional<UserRecordIdentifier> getUserIdentifierForValidToken(BearerAccessToken accessToken) throws IOException, OAuth2Exception{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to just return an empty optional rather than throwing an OAuth2Exception.

@kcondon
Copy link
Contributor

kcondon commented May 18, 2023

Tested with assistance from @pdurbin. Looks good from a basic functionality perspective. I know there are additional suggestions/to dos but seems ok to merge this step?

@kcondon kcondon merged commit 3d8ca99 into IQSS:develop May 18, 2023
9 of 10 checks passed
IQSS/dataverse (TO BE RETIRED / DELETED in favor of project 34) automation moved this from QA ✅ to Done 🚀 May 18, 2023
@pdurbin pdurbin added this to the 5.14 milestone May 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Account & User Info Size: 3 A percentage of a sprint. 2.1 hours.
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

As a developer, I'd like to use Bearer Token to send authenticated API requests
5 participants