Skip to content

Commit

Permalink
gplazma alise initial version of plugin
Browse files Browse the repository at this point in the history
Motivation:

A new service has been developed within the interTwin project: ALISE. An
ALISE service supports account linking; i.e., it allows a facility's
users to register their federated identity against their facility-local
identity.  This service is intended for situation where the facility's
IAM solution cannot easily be updated to support such federated account
linking.

ALISE works by the OIDC service (dCache) querying ALISE's REST API,
providing the user's identity ('sub' claim and the issuer URI).  The
response is the user's facility username and possibly a display name.

Modification:

A new gPlazma module is added that targets the ALISE service.

New gplazma configuraiton is added to support this plugin.

Result:

Without configuration changes, there is no user- or admin observable
changes.  This patch adds the integration possibility where dCache login
queries an ALISE service to learn a user's username.

Target: master
Requires-notes: yes
Requires-book: yes
Request: 10.1
Request: 10.0
Request: 9.2
  • Loading branch information
paulmillar authored and mksahakyan committed Aug 28, 2024
1 parent db6ea0f commit 6ab84e5
Show file tree
Hide file tree
Showing 14 changed files with 1,533 additions and 16 deletions.
143 changes: 127 additions & 16 deletions docs/TheBook/src/main/markdown/config-gplazma.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,117 @@ In the OP definition:

#### map Plug-ins

##### alise

[ALISE](https://github.com/m-team-kit/alise/) is a service developed through
the interTwin project. When deployed and configured, it allows a site's users
to register their federated identities (e.g. EGI Check-In, Helmholtz ID, some
community-managed INDICO-IAM service) against their site-local identity. This
registration process requires no admin intervention and a user typically does
this once. Once this link (between a user's federated and site-local
identities) is registered, ALISE allows a service (such as dCache) to discover
the local identity (a username) when that service presents that user's
federated identity (an OIDC `sub` claim).

ALISE is intended for sites that have identity management (IAM) solutions that
do not support federated identities. Other solutions may be preferable for
sites that have IAM solutions that support account linking; e.g., sites running
Keycloak may be able to provide the same functionality without running an
additional service.

The `alise` plugin processes a login request by taking the `sub` claim (e.g.,
as provided by the `oidc` plugin) and sending a request to the ALISE service.
If that request is successful then the plugin will learn the user's username
and (optionally) that user's display name. The `alise` plugin will cache
result of the ALISE query for a short period. This is to improve latency (of
subsequent queries) and to avoid placing too much load on the ALISE server.

When processing a login request, the `alise` plugin succeeds if it queries the
ALISE service with a `sub` claim and receives a corresponding local identity: a
username. The plugin fails if the ALISE service responds that no mapping is
known for this federated identity, if there is a problem making the request, or
if the login attempt does not contain a `sub` claim (either no access token was
provided or the `sub` claim was not extracted from the access token by the
`oidc` plugin).

**Configuration properties**

`gplazma.alise.endpoint`

This is a URL that forms the base for all HTTP queries to the ALISE service.
The default value is not valid; you must supply this configuration.

A typical value would look like `https://alise.example.org/`.

For comparison, a typical HTTP request to ALISE would look like:

https://alise.example.org/api/v1/target/vega-kc/mapping/issuer/95d[...]

The `gplazma.alise.endpoint` value is this URL update (but not including) the
`/api/v1` part.

`gplazma.alise.target`

A specific ALISE endpoint may serve multiple families of related services:
the targets. Targets are independent of each other: the account mapping
information of a target is independent of the account information any other
target.

The primary use-case for targets is to allow a single ALISE service to support
multiple sites; however, the concept could also be useful if a ALISE service
supports only a single site.

The default value is not valid; you must supply this configuration. A typical
value would be a simple string; e.g., `vega-kc`.

`gplazma.alise.apikey`

The API key is the authorisation that allows dCache to query ALISE for account
information. The [ALISE documentation](https://github.com/m-team-kit/alise/)
provides information on how to obtain the API key.

The following provides a quick summary of the process, using oidc-agent and
other common command-line tools. The

SOME_OP=EGI-CHECKIN # or whichever oidc-agent account is appropriate
TOKEN=$(oidc-token $SOME_OP)
TARGET=vega-kc # see gplazma.alise.target
APIKEY_ENDPOINT=https://alise.example.org/api/v1/target/$TARGET/get_apikey
APIKEY=$(curl -sH "Authorization: Bearer $TOKEN" $APIKEY_ENDPOINT \
| jq -r .apikey)

`gplazma.alise.timeout`

The time dCache will wait for the ALISE service to respond when requesting a
user's site-local identity. If there is no response within that time then the
alise plugin will fail the request. This, in turn, will (depending on gPlazma
configuration) likely result in gPlazma failing that login attempt.

The value is expressed as an ISO 8601 duration; for example, `PT5M` is five
minutes and `PT10S` is ten seconds.

`gplazma.alise.issuers`

The alise plugin can limit the federated identities that it will send to the
ALISE service, based on the issuer of the access token. The
`gplazma.alise.issuers` configuration property contains a space-separated list
of issuers, where each issuer is specified as either the dCache alias (see
`oidc` plugin) or the issuer's URI. As a special case, if this list is empty
then all tokens are sent to the ALISE service for mapping.

**Using with other plugins**

When successful, the `alise` plugin provides information about the user; in
particular, the user's username and (optionally) a display name. By itself,
this is insufficient for a successful gPlazma map phase, as the user's uid and
gid must also be obtained.

Out of the box, dCache supports multiple ways of obtaining the uid and gid from
a username. This could be done by querying an LDAP service (see `ldap` plugin),
an NIS service (see `nis` plugin) or the dCache server's local user account
lookup service (see `nsswitch` plugin). It is also possible to use explicit
configuration files (see `multimap` plugin).

##### kpwd

As a `map` plug-in it maps usernames to UID and GID. And as a `session` plug-in it adds root and home path information to the session based on the user’s username.
Expand Down Expand Up @@ -1480,7 +1591,7 @@ voms-proxy-info

## Using OpenID Connect

dCache also supports the use of OpenID Connect bearer tokens as a means of authentication.
dCache also supports the use of OpenID Connect bearer tokens as a means of authentication.

OpenID Connect is a federated identity system. The dCache users see federated identity as a way to use their existing username & password safely. From a dCache admin's point-of-view, this involves "outsourcing" responsibility for checking users identities to some external service: you must trust that the service is doing a good job.

Expand All @@ -1490,17 +1601,17 @@ OpenID Connect is a federated identity system. The dCache users see federated i
Common examples of Authorisation servers are Google, Indigo-IAM, Cern-Single-Signon etc.

As of version 2.16, dCache is able to perform authentication based on [OpendID Connect](http://openid.net/specs/openid-connect-core-1_0.html) credentials on its HTTP end-points. In this document, we outline the configurations necessary to enable this support for OpenID Connect.
As of version 2.16, dCache is able to perform authentication based on [OpendID Connect](http://openid.net/specs/openid-connect-core-1_0.html) credentials on its HTTP end-points. In this document, we outline the configurations necessary to enable this support for OpenID Connect.

OpenID Connect credentials are sent to dCache with Authorisation HTTP Header as follows
OpenID Connect credentials are sent to dCache with Authorisation HTTP Header as follows
`Authorization: Bearer <yaMMeexxx........>`. This bearer token is extracted, validated and verified against a **Trusted Authorisation Server** (Issue of the bearer token) and is used later to fetch additional user identity information from the corresponding Authorisation Server.

### Steps for configuration
### Steps for configuration

In order to configure the OpenID Connect support, we need to
In order to configure the OpenID Connect support, we need to

1. configure the gplazma plugins providing the support for authentication using OpenID credentials and mapping a verified OpenID credential to dCache specific `username`, `uid` and `gid`.
2. enabling the plugins in gplazma
2. enabling the plugins in gplazma

### Gplazma Plugins for OpenId Connect

Expand All @@ -1509,7 +1620,7 @@ The support for OpenID Connect in Cache is achieved with the help of two gplazma
#### OpenID Authenticate Plugin (oidc)
It takes the extracted OpenID connect credentials (Bearer Token) from the HTTP requests and validates it against a OpenID Provider end-point. The admins need to obtain this information from their trusted OpenID Provider such as Google.

In case of Google, the provider end-point can be obtained from the url of its [Discovery Document](http://openid.net/specs/openid-connect-core-1_0.html#OpenID.Discovery), e.g. https://accounts.google.com/.well-known/openid-configuration. Hence, the provider end-point in this case would be **accounts.google.com**.
In case of Google, the provider end-point can be obtained from the url of its [Discovery Document](http://openid.net/specs/openid-connect-core-1_0.html#OpenID.Discovery), e.g. https://accounts.google.com/.well-known/openid-configuration. Hence, the provider end-point in this case would be **accounts.google.com**.

This end-point has to be appended to the gplazma property **gplazma.oidc.hostnames**, which should be added to the layouts file. Multiple trusted OpenID providers can be added with space separated list as below.

Expand Down Expand Up @@ -1540,7 +1651,7 @@ The two plugins above must be enabled in the gplazma.conf.

> auth optional oidc
> map optional multimap
> map optional multimap
Restart dCache and check that there are no errors in loading these gplazma plugins.

Expand Down Expand Up @@ -1830,26 +1941,26 @@ Some file access examples:

Roles are a way of describing what capabilities a given user has. They constitute
a set of operations defined either explicitly or implicitly which the user who
is assigned that role is permitted to exercise.
is assigned that role is permitted to exercise.

Roles further allow users to act in more than one capacity without having to
change their basic identity. For instance, a "superuser" may wish to act as _janedoe_
Roles further allow users to act in more than one capacity without having to
change their basic identity. For instance, a "superuser" may wish to act as _janedoe_
for some things, but as an administrator for others, without having to reauthenticate.

While the role framework in dCache is designed to be extensible, there
currently exists only one recognized role, that of _admin_.
While the role framework in dCache is designed to be extensible, there
currently exists only one recognized role, that of _admin_.

To activate the use of the _admin_ role, the following steps are necessary.

1) Define the admin role using the property:
1) Define the admin role using the property:

```ini
gplazma.roles.admin-gid=<gid>
```

2) Add the _admin_ gid to the set of gids for any user who should have this capability.

3) Add the roles plugin to your gPlazma configuration (usually 'requisite' is sufficient):
3) Add the roles plugin to your gPlazma configuration (usually 'requisite' is sufficient):

session requisite roles

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.dcache.util;

import com.google.common.collect.Sets;
import java.net.URI;
import java.security.Principal;
import java.util.Collections;
import java.util.Set;
Expand All @@ -9,8 +10,10 @@
import org.dcache.auth.EmailAddressPrincipal;
import org.dcache.auth.ExemptFromNamespaceChecks;
import org.dcache.auth.FQANPrincipal;
import org.dcache.auth.FullNamePrincipal;
import org.dcache.auth.GidPrincipal;
import org.dcache.auth.GroupNamePrincipal;
import org.dcache.auth.OAuthProviderPrincipal;
import org.dcache.auth.OidcSubjectPrincipal;
import org.dcache.auth.UidPrincipal;
import org.dcache.auth.UserNamePrincipal;
Expand Down Expand Up @@ -52,12 +55,25 @@ public PrincipalSetMaker withUid(int uid) {
* Add a username Principal to the set.
*
* @param name the username to add
*
*/
public PrincipalSetMaker withUsername(String username) {
_principals.add(new UserNamePrincipal(username));
return this;
}

/**
* Add a Full Name Principal to the set.
*
* @param name the full name of the user.
*
*/
public PrincipalSetMaker withFullname(String name) {
_principals.add(new FullNamePrincipal(name));
return this;
}


/**
* Add a primary groupname Principal to the set.
*
Expand Down Expand Up @@ -152,6 +168,17 @@ public PrincipalSetMaker withOidc(String sub, String op) {
return this;
}

/**
* Add an OAuth2 Provider (OP) to the set.
*
* @param alias the name/alias of this OAuth2 Provider.
* @param uri the URI identity of the OAuth2 Provider.
*/
public PrincipalSetMaker withOauth2Provider(String alias, URI uri) {
_principals.add(new OAuthProviderPrincipal(alias, uri));
return this;
}

/**
* Add an Email principal to the set.
*
Expand Down
64 changes: 64 additions & 0 deletions modules/gplazma2-alise/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.dcache</groupId>
<artifactId>dcache-parent</artifactId>
<version>9.2.24-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>gplazma2-alise</artifactId>
<packaging>jar</packaging>

<name>gPlazma 2 ALISE plugin</name>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.dcache</groupId>
<artifactId>dcache-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.dcache</groupId>
<artifactId>gplazma2</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.npathai</groupId>
<artifactId>hamcrest-optional</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit 6ab84e5

Please sign in to comment.