-
Notifications
You must be signed in to change notification settings - Fork 535
OpenID Connect (OIDC) support #6433
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
Changes from all commits
9bc29ed
4f2d0b3
96d7055
3fd326c
908e15f
bd817fb
105e62f
e96799d
5118274
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,5 +20,6 @@ Installation Guide | |
| geoconnect | ||
| shibboleth | ||
| oauth2 | ||
| oidc | ||
| external-tools | ||
| advanced | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| OpenID Connect Login Options | ||
| ============================ | ||
|
|
||
| .. contents:: |toctitle| | ||
| :local: | ||
|
|
||
| Introduction | ||
| ------------ | ||
|
|
||
| The `OpenID Connect <https://openid.net/connect/>`_ (or OIDC) standard support is closely related to our :doc:`oauth2`, | ||
| as it has been based on the `OAuth 2.0 <https://oauth.net/2/>`_ standard. Quick summary: OIDC is using OAuth 2.0, but | ||
| adds a standardized way how authentication is done, while this is up to providers when using OAuth 2.0 for authentication. | ||
|
|
||
| Being a standard, you can easily enable the use of any OpenID connect compliant provider out there for login into your | ||
| Dataverse installation. | ||
|
|
||
| Some prominent provider examples: | ||
|
|
||
| - `Google <https://developers.google.com/identity/protocols/OpenIDConnect>`_ | ||
| - `Microsoft Azure AD <https://docs.microsoft.com/de-de/azure/active-directory/develop/v2-protocols-oidc>`_ | ||
| - `Yahoo <https://developer.yahoo.com/oauth2/guide/openid_connect>`_ | ||
| - ORCID `announced support <https://orcid.org/blog/2019/04/17/orcid-openid-connect-and-implicit-authentication>`_ | ||
|
|
||
| You can also either host an OpenID Connect identity management on your own or use a customizable hosted service: | ||
|
|
||
| - `Okta <https://developer.okta.com/docs/reference/api/oidc/>`_ is a hosted solution | ||
| - `Keycloak <https://www.keycloak.org>`_ is an open source solution for an IDM/IAM | ||
| - `Unity IDM <https://www.unity-idm.eu>`_ is another open source IDM/IAM solution | ||
|
|
||
| Other use cases and combinations | ||
| -------------------------------- | ||
|
|
||
| - Using your custom identity management solution might be a workaround when you seek for LDAP support, but | ||
| don't want to go for services like Microsoft Azure AD et al. | ||
| - You want to enable users to login in multiple different ways but appear as one account to Dataverse. This is | ||
| currently not possible within Dataverse itself, but hosting an IDM and attaching Dataverse solves it. | ||
| - You want to use the `eduGain Federation <https://edugain.org>`_ or other well known SAML federations, but don't want | ||
| to deploy Shibboleth as your service provider. Using an IDM solution in front easily allows you to use them | ||
| without hassle. | ||
| - There's also a `Shibboleth IdP (not SP!) extension <https://github.com/CSCfi/shibboleth-idp-oidc-extension>`_, | ||
| so if you already have a Shibboleth identity provider at your institution, you can reuse it more easily with Dataverse. | ||
| - In the future, OpenID Connect might become a successor to the large scale R&E SAML federations we have nowadays. | ||
| See also `OpenID Connect Federation Standard <https://openid.net/specs/openid-connect-federation-1_0.html>`_ (in development) | ||
|
|
||
| How to use | ||
| ---------- | ||
|
|
||
| Just like with :doc:`oauth2` you need to obtain a *Client ID* and a *Client Secret* from your provider(s). | ||
|
|
||
| .. note:: | ||
| Dataverse does not support `OpenID Connect Dynamic Registration <https://openid.net/specs/openid-connect-registration-1_0.html>`_. | ||
| You need to apply for credentials out-of-band. | ||
|
|
||
| Dataverse will discover all necessary metadata for a given provider on its own (this is `part of the standard | ||
| <http://openid.net/specs/openid-connect-discovery-1_0.html>`_). | ||
|
|
||
| To enable this, you need to specify an *Issuer URL* when creating the configuration for your provider (see below). | ||
|
|
||
| Finding the issuer URL is best done by searching for terms like "discovery" in the documentation of your provider. | ||
| The discovery document is always located at ``<issuer url>/.well-known/openid-configuration`` (standardized). | ||
| To be sure, you can always lookup the ``issuer`` value inside the live JSON-based discovery document. | ||
|
|
||
| Please create a file like this, replacing every ``<...>`` with your values: | ||
|
|
||
| .. code-block:: json | ||
| :caption: my-oidc-provider.json | ||
|
|
||
| { | ||
| "id":"<a unique id>", | ||
| "factoryAlias":"oidc", | ||
| "title":"<a title - shown in UI>", | ||
| "subtitle":"<a subtitle - currently unused in UI>", | ||
| "factoryData":"type: oidc | issuer: <issuer url> | clientId: <client id> | clientSecret: <client secret>", | ||
| "enabled":true | ||
| } | ||
|
|
||
| Now load the configuration into Dataverse using the same API as with :doc:`oauth2`: | ||
|
|
||
| ``curl -X POST -H 'Content-type: application/json' --upload-file my-oidc-provider.json http://localhost:8080/api/admin/authenticationProviders`` | ||
|
|
||
| Dataverse will automatically try to load the provider and retrieve the metadata. Watch the Glassfish log for errors. | ||
| You should see the new provider under "Other options" on the Log In page, as described in the :doc:`/user/account` | ||
| section of the User Guide. | ||
|
|
||
| By default, the Log In page will show the "builtin" provider, but you can adjust this via the ``:DefaultAuthProvider`` | ||
| configuration option. For details, see :doc:`config`. | ||
|
|
||
| .. hint:: | ||
| In contrast to our :doc:`oauth2`, you can use multiple providers by creating distinct configurations enabled by | ||
| the same technology and without modifying the Dataverse code base (standards for the win!). | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| import com.github.scribejava.core.model.Verb; | ||
| import com.github.scribejava.core.oauth.AuthorizationUrlBuilder; | ||
| import com.github.scribejava.core.oauth.OAuth20Service; | ||
| import edu.harvard.iq.dataverse.LoginPage; | ||
| import edu.harvard.iq.dataverse.authorization.AuthenticatedUserDisplayInfo; | ||
| import edu.harvard.iq.dataverse.authorization.AuthenticationProvider; | ||
| import edu.harvard.iq.dataverse.authorization.AuthenticationProviderDisplayInfo; | ||
|
|
@@ -22,6 +23,8 @@ | |
|
|
||
| /** | ||
| * Base class for OAuth2 identity providers, such as GitHub and ORCiD. | ||
| * | ||
| * TODO: this really should become an interface (contract with {@link OAuth2LoginBackingBean}) when refactoring package | ||
| * | ||
| * @author michael | ||
| */ | ||
|
|
@@ -90,12 +93,16 @@ public String toString() { | |
| protected String clientSecret; | ||
| protected String baseUserEndpoint; | ||
| protected String redirectUrl; | ||
|
|
||
| /** | ||
| * List of scopes to be requested for authorization at identity provider. | ||
| * Defaults to empty so no scope will be requested (use case: public info from GitHub) | ||
| */ | ||
| protected List<String> scope = Arrays.asList(""); | ||
|
|
||
| /** | ||
| * TODO: when refactoring the package to be about token flow auth, this hard dependency should be removed. | ||
| */ | ||
| public abstract DefaultApi20 getApiInstance(); | ||
|
|
||
| protected abstract ParsedUserResponse parseUserResponse( String responseBody ); | ||
|
|
@@ -207,6 +214,14 @@ public AuthenticationProviderDisplayInfo getInfo() { | |
| return new AuthenticationProviderDisplayInfo(getId(), getTitle(), getSubTitle()); | ||
| } | ||
|
|
||
| /** | ||
| * Used in {@link LoginPage#listAuthenticationProviders()} for sorting the providers in the UI | ||
| * TODO: this might be extended to use a value set by the admin when configuring the provider via JSON. | ||
| * @return an integer value (sort ascending) | ||
| */ | ||
| @Override | ||
| public int getOrder() { return 100; } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if there are more than 100 authentication providers? Some have the same number? Is it ok to have two 42s?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it doesn't matter if some have the same number, as they are sorted by number first, then by name. This is mostly about sorting Builtin first (order = 1), Shib second (order=20) and OAuth last (all order = 100), as it has been sorted before my refactoring. Once we have a configurable value for this, you could also realize sth. like provider A first, then all the others. |
||
|
|
||
| @Override | ||
| public String getId() { | ||
| return id; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the change above necessary for OIDC to work? I don't think so. It does look like a nice cleanup though. I like how it's deterministic. Perhaps this change should be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually yes it is. From this function,
authSvc.getAuthenticationProviderIdsSorted()was called, which is deleted below. This was done in 3fd326c and here's what I wrote in the commit log: