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

Generic OIDC provider support #10152

Merged
merged 6 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
139 changes: 138 additions & 1 deletion docs/developer-guide/integrations/users/openId.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You can remove the `geostore` entry from `authenticationProviders` list to remov

MapStore allows to integrate with the following OpenID providers.

- OpenID Connect (generic)
- Google
- Keycloak

Expand All @@ -27,7 +28,143 @@ For each service you want to add you have to:
- modify `localConfig.json` adding a proper entry to the `authenticationProviders`.
offtherailz marked this conversation as resolved.
Show resolved Hide resolved

!!! note
For the moment we can configure only one authentication per service type (only one for google, only one for keycloak ...).
For the moment we can configure only one authentication per service type (only one for `oidc`, one for `google`, one for `keycloak` ...).

### OpenID connect (generic)

MapStore allows to configure a generic OpenID Connect provider. This is useful when you have to configure a provider that is not directly supported by MapStore.
In order to configure the generic OpenID provider you have to:

- Configure and get the information from your OpenID provider (generically configure the valid redirect URI and get the `discoveryUrl`, `clientId`, `clientSecret`).
- create/edit `mapstore-ovr.properties` file (in data-dir or class path) to configure the generic provider
- add an entry for `oidc` in `authenticationProviders` inside `localConfig.json` file.

#### Configure and get the information from your OpenID provider

This depends on the specific OpenID provider you are using. Here we show an example with Microsoft Azure.

##### Example with Microsoft Azure

Microsoft Azure provides OpenID Connect support. This is an example of how to configure MapStore to use Microsoft Azure as an OpenID provider. The same steps can be applied to other OpenID providers. Please refer to the specific documentation of the OpenID provider you are using.

Here a quick summary of the steps to configure Microsoft Azure as an OpenID provider and get the information needed to configure MapStore:

1. Create a new application ![Create azure application](img/azure-1.jpg)
2. Set the proper valid redirect URLs ![set redirect URL](img/azure-2.jpg) to: `https://<your-domain>/mapstore/rest/geostore/openid/oidc/callback`
3. Create and copy client secret ![Create and copy client secret](img/azure-3.jpg)
4. Add optional claims if needed ![Add optional claims](img/azure-4.jpg)
5. Copy endpoints and data to configure MapStore ![Copy endpoints](img/azure-5.jpg)

These steps are based on the [Microsoft Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
Please refer the official documentation for any detail or additional configuration.

Here also some sample configurations for MapStore (see the following sections for details):

`mapstore-ovr.properties`:

```properties
# enables the keycloak OpenID Connect filter
oidcOAuth2Config.enabled=true

# note: this is the client id you have created in Keycloak
oidcOAuth2Config.clientId=<CLIENT_ID>
oidcOAuth2Config.clientSecret=<CLIENT_SECRET>

# DISCOVERY_URL something like https://login.microsoftonline.com/abc-dfe-ghi-123-345-567-789/v2.0/.well-known/openid-configuration
oidcOAuth2Config.discoveryUrl=<DISCOVERY_URL>
oidcOAuth2Config.sendClientSecret=true
# create the user if not present
oidcOAuth2Config.autoCreateUser=true
# Here you have to set your redirect URI (here is configured for localhost)
oidcOAuth2Config.redirectUri=http://localhost:8080/mapstore/rest/geostore/openid/oidc/callback
# Internal redirect URI (you can set it to relative path like this `../../..` to make this config work across domain)
oidcOAuth2Config.internalRedirectUri=http://localhost:8080/mapstore
```

`localConfig.json.patch` ( *with a custom title and an image with the Microsoft logo* to show in the login form)

```json
{
"authenticationProviders" [
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
{
"type": "openID",
"provider": "oidc",
"title": "Microsoft",
"imageURL": "data:image/svg+xml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgdmlld0JveD0iMCAwIDI1IDI1IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGl0ZW1wcm9wPSJsb2dvIiBpdGVtc2NvcGU9Iml0ZW1zY29wZSI+CgkJCTxwYXRoIGQ9Ik0xMS41MjE2IDAuNUgwVjExLjkwNjdIMTEuNTIxNlYwLjVaIiBmaWxsPSIjZjI1MDIyIj48L3BhdGg+CgkJCTxwYXRoIGQ9Ik0yNC4yNDE4IDAuNUgxMi43MjAyVjExLjkwNjdIMjQuMjQxOFYwLjVaIiBmaWxsPSIjN2ZiYTAwIj48L3BhdGg+CgkJCTxwYXRoIGQ9Ik0xMS41MjE2IDEzLjA5MzNIMFYyNC41SDExLjUyMTZWMTMuMDkzM1oiIGZpbGw9IiMwMGE0ZWYiPjwvcGF0aD4KCQkJPHBhdGggZD0iTTI0LjI0MTggMTMuMDkzM0gxMi43MjAyVjI0LjVIMjQuMjQxOFYxMy4wOTMzWiIgZmlsbD0iI2ZmYjkwMCI+PC9wYXRoPgoJCTwvc3ZnPgo="
},
{
"type": "basic",
"provider": "geostore"
}
]

}
```

#### Configure MapStore back-end for OIDC OpenID

In order to configure the generic OpenID provider you have to:

- create/edit `mapstore-ovr.properties` file (in data-dir or class path) to configure the generic provider this way:

```properties
# enables the keycloak OpenID Connect filter
oidcOAuth2Config.enabled=true

# note: this is the client id have to be present on the OpenID provider
oidcOAuth2Config.clientId=mapstore-server
oidcOAuth2Config.clientSecret=<THE_CLIENT_SECRET>
# the discovery URL
oidcOAuth2Config.discoveryUrl=http://keycloak:8080/auth/realms/mapstore/.well-known/openid-configuration
oidcOAuth2Config.sendClientSecret=true
# create the user if not present
oidcOAuth2Config.autoCreateUser=true
oidcOAuth2Config.redirectUri=http://localhost:8080/mapstore/rest/geostore/openid/oidc/callback
# Internal redirect URI (you can set it to relative path like this `../../..` to make this config work across domain)
oidcOAuth2Config.internalRedirectUri=http://localhost:8080/mapstore
# user name attribute (default is `email`)
# oidcOAuth2Config.principalKey=email
# Optional role claims, if a claim contains roles, you can map them to MapStore roles. (roles can be only ADMIN or USER)
# oidcOAuth2Config.rolesClaim=roles
# Optional group claims, if a claim contains groups, you can map them to MapStore groups.
# oidcOAuth2Config.groupsClaim=groups
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
```

- `oidcOAuth2Config.clientId`: the client id. This is the client id that have to be present on the OpenID provider
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
- `oidcOAuth2Config.clientSecret`: the client secret. This is the client secret for the client id on the OpenID provider
- `oidcOAuth2Config.discoveryUrl`: the discovery URL. This is the URL that contains all the information for the specific service.
- `oidcOAuth2Config.sendClientSecret`: if `true`, the client secret will be sent to the OpenID provider. If `false`, the client secret will not be sent.
- `oidcOAuth2Config.autoCreateUser`: if `true`, the user will be created if not present in the MapStore database. If `false`, the user will not be created ( useful if the user is managed by an external service like Keycloak or LDAP).
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
- `oidcOAuth2Config.redirectUri`: the redirect URI. This is the URI that the OpenID provider, and it must be the effective URI of the MapStore application, with the path `/rest/geostore/openid/oidc/callback`.
Copy link
Member

Choose a reason for hiding this comment

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

There is a missing part here. Please reformulate better.

- `oidcOAuth2Config.internalRedirectUri`: the internal redirect URI. This is the URI that the MapStore will redirect to after the login. It must be the effective URI of the MapStore application.
- `oidcOAuth2Config.principalKey`: (*optional*) the user name attribute. This is the attribute that will be used as the user name. The default is `email`.
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
- `oidcOAuth2Config.rolesClaim`: (*optional*) the role claims. If a claim contains roles, you can map them to MapStore roles. The roles can be only `ADMIN` or `USER`. If the claim is not present, the default role will be `USER`.
- `oidcOAuth2Config.groupsClaim`: (*optional*) the group claims. If a claim contains groups, you can map them to MapStore groups. If the claim is not present, no group will be assigned (except the default `everyone` group).
offtherailz marked this conversation as resolved.
Show resolved Hide resolved

!!! note
The `rolesClaim` and `groupsClaim` are optional. If you don't need to map roles or groups, you can omit them. At the moment, there is no mapping for roles and groups for the generic OIDC provider. If you need to map roles and groups, you can use the `keycloak` provider.

#### Configure MapStore front-end for OIDC OpenID

- Add an entry for `oidc` in `authenticationProviders` inside `localConfig.json` file.

```json
{
"authenticationProviders": [
{
"type": "openID",
"provider": "oidc",
"title": "My custom identity provider"
},
{
"type": "basic",
"provider": "geostore"
}
]
}
```

You can customize the `title` to show in the login form, add an `imageURL` or use only one `authenticationProviders`, removing the `geostore` entry, if you want to use only the OpenID provider. In this case the user will be redirected directly to the OpenID provider without showing the login form.
offtherailz marked this conversation as resolved.
Show resolved Hide resolved

### Google

Expand Down
30 changes: 29 additions & 1 deletion docs/developer-guide/mapstore-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,34 @@ This is a list of things to check if you want to update from a previous version
- Optionally check also accessory files like `.eslinrc`, if you want to keep aligned with lint standards.
- Follow the instructions below, in order, from your version to the one you want to update to.

## Migration from 2024.01.00 to 2024.02.00

### Integration with openID Connect

A generic OpenID Connect (OIDC) authentication support has been introduced in MapStore. This feature allows to authenticate users using an OIDC provider, like Keycloak, Okta, Google, Azure, etc.

In order to have this feature working, you need to update in your project the `geostore-spring-security.xml` file in your project, if it has been customized and you are not using the default one.
offtherailz marked this conversation as resolved.
Show resolved Hide resolved
If you are using the default one, you can skip this step.

Here the changes to apply if needed:

```diff
@@ -24,6 +24,7 @@
<security:custom-filter ref="sessionTokenProcessingFilter" after="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="keycloakFilter" before="BASIC_AUTH_FILTER"/>
<security:custom-filter ref="googleOpenIdFilter" after="BASIC_AUTH_FILTER"/>
+ <security:custom-filter ref="oidcOpenIdFilter" before="OPENID_FILTER"/> <!-- ADD a filter with this ref -->
<security:anonymous />
</security:http>

@@ -52,6 +53,7 @@

<!-- OAuth2 beans -->
<context:annotation-config/>
+ <bean id="oidcSecurityConfiguration" class="it.geosolutions.geostore.services.rest.security.oauth2.openid_connect.OpenIdConnectSecurityConfiguration"/> <!-- add this bean to configure the integration -->

<bean id="googleSecurityConfiguration" class="it.geosolutions.geostore.services.rest.security.oauth2.google.OAuthGoogleSecurityConfiguration"/>

offtherailz marked this conversation as resolved.
Show resolved Hide resolved
## Migration from 2023.02.02 to 2024.01.00

### TOC plugin refactor
Expand All @@ -33,7 +61,7 @@ The table of content (TOC) has been refactored with following changes:
- `activateQueryTool` removed property, now the button will be directly added by `FilterLayer` plugin, when available
- `activateDownloadTool` removed property, now the button will be added directly from `LayerDownload` when available
- `activateMetedataTool` removed property, now the button will be added directly from `MetadataInfo` when availables
- `checkPlugins` remove property, now availability of tools rely on the related plugin so this check is not needed anymore
- `checkPlugins` remove property, now availability of tools rely on the related plugin so this check is not needed anymore
- `showFullTitleOnExpand` removed property, the new style allows for seeing the full title inline without duplicating it
- `metadataTemplate` this configuration has been moved to `MetadataInfo` plugin
- `metadataOptions` this configuration has been moved to `MetadataInfo` plugin
Expand Down
7 changes: 6 additions & 1 deletion product/config/db/geostore-spring-security-db.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<security:custom-filter ref="sessionTokenProcessingFilter" after="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="keycloakFilter" before="BASIC_AUTH_FILTER"/>
<security:custom-filter ref="googleOpenIdFilter" after="BASIC_AUTH_FILTER"/>
<security:custom-filter ref="oidcOpenIdFilter" before="OPENID_FILTER"/>
<security:anonymous />
</security:http>

Expand All @@ -50,9 +51,13 @@
<bean id="preauthenticatedAuthenticationProvider" class="it.geosolutions.geostore.services.rest.security.PreAuthenticatedAuthenticationProvider">
</bean>

<!-- OAuth2 beans -->
<context:annotation-config/>
<!-- OAuth2 beans -->

<!-- Generic OIDC -->
<bean id="oidcSecurityConfiguration" class="it.geosolutions.geostore.services.rest.security.oauth2.openid_connect.OpenIdConnectSecurityConfiguration"/>

<!-- Google -->
<bean id="googleSecurityConfiguration" class="it.geosolutions.geostore.services.rest.security.oauth2.google.OAuthGoogleSecurityConfiguration"/>

<!-- Keycloak -->
Expand Down