Skip to content

Commit

Permalink
Support for Keycloak OpenID (#8345)
Browse files Browse the repository at this point in the history
  • Loading branch information
taba90 authored Jun 27, 2022
1 parent 44ac4c7 commit 5220f75
Show file tree
Hide file tree
Showing 23 changed files with 423 additions and 82 deletions.
2 changes: 1 addition & 1 deletion docs/developer-guide/externalized-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ In `datadir_path/env.properties`:
geoserverUrl=https://demo.geo-solutions.it/geoserver/wms
```

This allows to have in `datadir_path/env.properties` a set of variables that can be used in overrides (even in different places) that are indicated by `overrides.mappings`.
This allows to have in `datadir_path/env.properties` a set of variables that can be used in overrides (even in different places) that are indicated by `overrides.mappings`.

**Note:** `env.properties` should **not be placed** in classpath folder

Expand Down
64 changes: 0 additions & 64 deletions docs/developer-guide/integrations/openId.md

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions docs/developer-guide/integrations/users/img/mapstore-server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"clientId": "mapstore-server",
"rootUrl": "http://localhost:8081",
"adminUrl": "",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/*",
"http://localhost:8082/*"
],
"webOrigins": [
""
],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": true,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"access.token.lifespan": "300",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"frontchannel.logout.session.required": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature.keyinfo.ext": "false",
"use.refresh.tokens": "true",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"require.pushed.authorization.requests": "false",
"saml.client.signature": "false",
"saml.allow.ecp.flow": "false",
"id.token.as.detached.signature": "false",
"saml.assertion.signature": "false",
"client.secret.creation.time": "1655740901",
"saml.encrypt": "false",
"saml.server.signature": "false",
"exclude.session.state.from.auth.response": "false",
"saml.artifact.binding": "false",
"saml_force_name_id_format": "false",
"acr.loa.map": "{}",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"token.response.type.bearer.lower-case": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"acr",
"roles",
"profile",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
167 changes: 167 additions & 0 deletions docs/developer-guide/integrations/users/openId.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Integration with OpenID connect

MapStore allows to integrate and login using some common [OpenID connect](https://openid.net/connect/) services. Having this support properly configured, you can make MapStore users able to login with the given OpenID service.

## Customizing logo an text in Login Form

For details about the configuration for a specific service, please refer to the specific section below. For details about `authenticationProviders` optional values (e.g. to customize icon and/or text to show), refer to the documentation of the [LoginPlugin](https://mapstore.geosolutionsgroup.com/mapstore/docs/api/plugins#plugins.Login).

By default `authenticationProviders` is `{"type": "basic", "provider": "geostore"}`, that represents the standard login on **MapStore** with username and password. With the default configuration, when the user try to login, MapStore will show the classic login form.

It is possible to add other providers to the list (e.g. `openid`) and they will be added as options to the login window.
You can remove the `geostore` entry from `authenticationProviders` list to remove the login form from the possible login systems.

!!! note
If only one OpenID entry is present in `authenticationProviders` (and no `geostore` entry available), clicking on login in the login menu will not show any intermediate window and you will be redirected directly to the OpenID provider configured. If more than one entry is present in `authenticationProviders` list, the user will have to choose one of them to be authenticated.

## Supported OpenID services

MapStore allows to integrate with the following OpenID providers.

- Google
- Keycloak

For each service you want to add you have to:

- properly configure the backend
- modify `localConfig.json` adding a proper entry to the `authenticationProviders`.

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

### Google

#### Create Oauth 2.0 credentials on Google Console

In order to setup the openID connection you have to setup a project in Google API Console to obtain Oauth 2.0 credentials and configure them.

- Open Google developer console and, from credentials section, create a new credential of type **Oauth client ID**

<img src="../img/google-create-credentials.jpg" class="ms-docimage" style="max-width:500px;"/>

- Set the **Application Type** to **Web Application**, name it as you prefer and configure the root of the application as an authorized redirect URI. Then click on **Create**

<img src="../img/google-create-oauth2.jpg" class="ms-docimage" style="max-width:500px;"/>

- After creation you will obtain **ClientID** and **Client Secret** to use to configure MapStore.

Please follow the [Google documentation](https://developers.google.com/identity/protocols/oauth2/openid-connect) for any detail or additional configuration.

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

After the setup, you will have to:

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

```properties

# enables the google OpenID Connect filter
googleOAuth2Config.enabled=true

#clientId and clientSecret
googleOAuth2Config.clientId=<the_client_id_from_google_dev_console>
googleOAuth2Config.clientSecret=<the_client_secret_from_google_dev_console>

# create the user if not present
googleOAuth2Config.autoCreateUser=true

# Redirect URL
googleOAuth2Config.redirectUri=https://<your-appliction-domain>/mapstore/rest/geostore/openid/google/callback
# Internal redirect URI (you can set it to relative path like this `../../..` to make this config work across domain)
googleOAuth2Config.internalRedirectUri=https://<your-appliction-domain>/mapstore/

## discoveryUrl: contains all the information for the specific service.
googleOAuth2Config.discoveryUrl=https://accounts.google.com/.well-known/openid-configuration
#If the `discoveryUrl` has not been specified, you can manually configure the following options.
```

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

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

```json
{
"authenticationProviders": [
{
"type": "openID",
"provider": "google"
},
{
"type": "basic",
"provider": "geostore"
}
]
}
```

### Keycloak

[Keycloak](https://www.keycloak.org/) is an open source identity and access management application widely used. MapStore has the ability to integrate with keycloak:

- Using the standard OpenID protocol
- Supporting SSO (not yet implemented)
- Integrating with users and roles, as well as for ldap. (not yet implemented)

In this section you can see how to configure keycloak as a standard OpenID provider

#### Configure keycloak Client

Create a new Client on keycloak. In this guide we will name it `mapstore-server` (because if you need to configure SSO, we may need another key to call `mapstore-client`)

<img src="../img/kc-create-client.jpg" class="ms-docimage" style="max-width:500px;"/>
<img src="../img/kc-create-mapstore-server.jpg" class="ms-docimage" style="max-width:500px;"/>

- Configure it as `Confidential` setting the Redirect-URL with your MapStore base root, with a `*` at the end (e.g. `https://my.mapstore.site.com/mapstore/*`)

<img src="../img/kc-configure-mapstore-server.jpg" class="ms-docimage" style="max-width:500px;"/>

- Click on Save button, then open the *Installation* tab, select the `Keycloak OIDC JSON` format, and copy the JSON displayed below.

<img src="../img/kc-copy-config-server.jpg" class="ms-docimage" style="max-width:500px;"/>

### Configure MapStore back-end for Keycloak OpenID

- create/edit `mapstore-ovr.properties` file (in data-dir or class path) to configure the keycloak provider this way:
- `keycloakOAuth2Config.jsonConfig`: insert the JSON copied, removing all the spaces
- `keycloakOAuth2Config.redirectUri`: need to be configured to point to your application at the path `<base-app-url>/rest/geostore/openid/keycloak/callback`, e.g. `https://my.mapstore.site.com/mapstore/rest/geostore/openid/keycloak/callback`
- `keycloakOAuth2Config.internalRedirectUri` can be set to your application root, e.g. `https://my.mapstore.site.com/mapstore/`
- `keycloakOAuth2Config.autoCreateUser`: true if you want to create user on DB on login (if you are not using any other user integration e.g. `ldap`, `keycloak`)

```properties
# enables the keycloak OpenID Connect filter
keycloakOAuth2Config.enabled=false

# Configuration
keycloakOAuth2Config.jsonConfig=<copy-here-the-json-config-from-keycloak-removing-all-the-spaces>


# Redirect URLs
# - Redirect URL: need to be configured to point to your application at the path <base-app-url>/rest/geostore/openid/keycloak/callback
# e.g. `https://my.mapstore.site.com/mapstore/mapstore/rest/geostore/openid/keycloak/callback`
keycloakOAuth2Config.redirectUri=https://localhost:9191/mapstore/rest/geostore/openid/keycloak/callback
# - Internal redirect URL when logged in (typically the home page of MapStore, can be relative)
keycloakOAuth2Config.internalRedirectUri=https://my.mapstore.site.com/mapstore/

# Create user (if you are using local database, this should be set to true)
keycloakOAuth2Config.autoCreateUser=true

```

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

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

```json
{
"authenticationProviders": [
{
"type": "openID",
"provider": "keycloak"
},
{
"type": "basic",
"provider": "geostore"
}
]
}
```
11 changes: 8 additions & 3 deletions docs/developer-guide/mapstore-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ This is a list of things to check if you want to update from a previous version

### Support for OpenID

MapStore introduced support for OpenID. In order to have this functionalities and to be aligned with the latest version of MapStore you have to update the following files in your projects:
MapStore introduced support for OpenID for google and keycloak. In order to have this functionalities and to be aligned with the latest version of MapStore you have to update the following files in your projects:

- `geostore-spring-security.xml` (your custom spring security context) have to be updated adding the beans and the `security:custom-filter` entry in the `<security:http>` entry, as here below:

```diff
<security:csrf disabled="true"/>
<security:custom-filter ref="authenticationTokenProcessingFilter" before="FORM_LOGIN_FILTER"/>
<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:anonymous />
</security:http>
Expand All @@ -49,6 +50,10 @@ MapStore introduced support for OpenID. In order to have this functionalities an
+
+ <bean id="googleSecurityConfiguration" class="it.geosolutions.geostore.services.rest.security.oauth2.google.OAuthGoogleSecurityConfiguration"/>
+
+ <!-- Keycloak -->
+
+ <bean id="keycloakConfig" class="it.geosolutions.geostore.services.rest.security.keycloak.KeyCloakSecurityConfiguration"/>
+
+ <!-- END OAuth2 beans-->
</beans>

Expand Down Expand Up @@ -244,11 +249,11 @@ Contents of your `pluginsConfig.json` need to be reviewed to allow usage of new
Please refer to the [extensions](../extensions/#managing-drawing-interactions-conflict-in-extension) documentation to know how to update your extensions.

### Using `terrain` layer type to define 3D map elevation profile
A new `terrain` layer type has been created in order to provide more options and versatility when defining an elevation profile for the 3D map terrain.
A new `terrain` layer type has been created in order to provide more options and versatility when defining an elevation profile for the 3D map terrain.
This `terrain` layer will substitute the former `wms` layer (with `useForElevation` attribute) used to define the elevation profile.

The `additionalLayers` object on the `localConfig.json` file should adhere now to the [terrain layer configuration](../maps-configuration/#terrain).
Serve the following code as an example:
Serve the following code as an example:

```json
{
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ nav:
- users:
- GeoServer: 'developer-guide/integrations/users/geoserver.md'
- LDAP: 'developer-guide/integrations/users/ldap.md'
- OpenId Connect/Oauth2: 'developer-guide/integrations/users/openId.md'
- OpenId Connect: 'developer-guide/integrations/users/openId.md'
- Projects:
- MapStore Projects: 'developer-guide/mapstore-projects.md'
- Project Creation Script: 'developer-guide/project-creation-script.md'
Expand Down
5 changes: 5 additions & 0 deletions product/config/db/geostore-spring-security-db.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<security:csrf disabled="true"/>
<security:custom-filter ref="authenticationTokenProcessingFilter" before="FORM_LOGIN_FILTER"/>
<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:anonymous />
</security:http>
Expand Down Expand Up @@ -60,5 +61,9 @@

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

<!-- Keycloak -->

<bean id="keycloakConfig" class="it.geosolutions.geostore.services.rest.security.keycloak.KeyCloakSecurityConfiguration"/>

<!-- END OAuth2 beans-->
</beans>
Loading

0 comments on commit 5220f75

Please sign in to comment.