Search in sources :

Example 1 with OpenIdGroupPrincipal

use of org.dcache.auth.OpenIdGroupPrincipal in project dcache by dCache.

the class WlcgProfile method wlcgGroups.

private List<Principal> wlcgGroups(Map<String, JsonNode> claims) {
    if (!claims.containsKey("wlcg.groups")) {
        return Collections.emptyList();
    }
    JsonNode groups = claims.get("wlcg.groups");
    if (!groups.isArray()) {
        LOGGER.debug("Ignoring malformed \"wlcg.groups\": not an array");
        return Collections.emptyList();
    }
    List<Principal> principals = new ArrayList<>();
    for (JsonNode group : groups) {
        if (!group.isTextual()) {
            LOGGER.debug("Ignoring malformed \"wlcg.groups\" value: {}", group);
            continue;
        }
        var groupName = group.asText();
        var principal = new OpenIdGroupPrincipal(groupName);
        principals.add(principal);
    }
    return principals;
}
Also used : ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal) OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal) Principal(java.security.Principal)

Example 2 with OpenIdGroupPrincipal

use of org.dcache.auth.OpenIdGroupPrincipal in project dcache by dCache.

the class OidcProfile method addWlcgGroups.

/**
 * Parse group-membership information, as described in "WLCG Common JWT Profiles" v1.0.  For
 * details, see: https://zenodo.org/record/3460258#.YVGMLyXRaV4
 * <p>
 * Here is an example:
 * <pre>
 * "wlcg.groups": [
 *     "/dteam/VO-Admin",
 *     "/dteam",
 *     "/dteam/itcms"
 * ],
 * </pre>
 *
 * REVISIT: should this be supported in the 'oidc' profile?  The semantics of this claim are
 * defined in the WLCG AuthZ JWT profile document, which is supported by a different profile.
 *
 * @param userInfo   The JSON node describing the user.
 * @param principals The set of principals into which any group information is to be added.
 */
private void addWlcgGroups(Map<String, JsonNode> claims, Set<Principal> principals) {
    if (!claims.containsKey("wlcg.groups")) {
        return;
    }
    JsonNode groups = claims.get("wlcg.groups");
    if (!groups.isArray()) {
        LOGGER.debug("Ignoring malformed \"wlcg.groups\": not an array");
        return;
    }
    for (JsonNode group : groups) {
        if (!group.isTextual()) {
            LOGGER.debug("Ignoring malformed \"wlcg.groups\" value: {}", group);
            continue;
        }
        var groupName = group.asText();
        var principal = new OpenIdGroupPrincipal(groupName);
        principals.add(principal);
    }
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal)

Example 3 with OpenIdGroupPrincipal

use of org.dcache.auth.OpenIdGroupPrincipal in project dcache by dCache.

the class SciTokenPlugin method authenticate.

@Override
public void authenticate(Set<Object> publicCredentials, Set<Object> privateCredentials, Set<Principal> identifiedPrincipals, Set<Restriction> restrictions) throws AuthenticationException {
    List<String> tokens = privateCredentials.stream().filter(BearerTokenCredential.class::isInstance).map(BearerTokenCredential.class::cast).map(BearerTokenCredential::getToken).filter(JsonWebToken::isCompatibleFormat).collect(Collectors.toList());
    checkAuthentication(!tokens.isEmpty(), "no JWT bearer token");
    checkAuthentication(tokens.size() == 1, "multiple JWT bearer tokens");
    try {
        JsonWebToken token = checkValid(new JsonWebToken(tokens.get(0)));
        Issuer issuer = issuerOf(token);
        validateWlcgVersionClaim(token);
        Collection<Principal> principals = new ArrayList<>();
        // REVISIT consider introducing an SPI to allow plugable support for handling claims.
        Optional<String> sub = token.getPayloadString("sub");
        sub.map(s -> new JwtSubPrincipal(issuer.getId(), s)).ifPresent(principals::add);
        sub.map(s -> new OidcSubjectPrincipal(s, issuer.getId())).ifPresent(principals::add);
        Optional<String> jti = token.getPayloadString("jti");
        jti.map(s -> new JwtJtiPrincipal(issuer.getId(), s)).ifPresent(principals::add);
        token.getPayloadStringOrArray("wlcg.groups").stream().map(OpenIdGroupPrincipal::new).forEach(principals::add);
        checkAuthentication(sub.isPresent() || jti.isPresent(), "missing sub and jti claims");
        principals.add(issuer.getOpIdentity());
        List<AuthorisationSupplier> scopes = token.getPayloadString("scope").map(SciTokenPlugin::parseScope).orElse(Collections.emptyList());
        if (scopes.isEmpty()) {
            // No scopes defined -> not explicit authorisation; however, perhaps the client
            // is allowed to do something based on asserted group-membership or from their
            // membership of the VO (implied by the OP issuing any token at all).
            // This only makes sense if the token follows the WLCG AuthZ profile.  A SciToken
            // is not valid (or useful) without at least one authorisation statements in the
            // 'scope' claim
            checkAuthentication(token.getPayloadString("wlcg.ver").isPresent(), "not a SciToken or WLCG profile.");
        // allow login to proceed with whatever information we've gained so far.
        } else {
            principals.addAll(issuer.getUserIdentity());
            Restriction r = buildRestriction(issuer.getPrefix(), scopes);
            LOGGER.debug("Authenticated user with restriction: {}", r);
            restrictions.add(r);
            principals.add(new ExemptFromNamespaceChecks());
        }
        identifiedPrincipals.addAll(principals);
    } catch (IOException e) {
        throw new AuthenticationException(e.getMessage());
    }
}
Also used : ExemptFromNamespaceChecks(org.dcache.auth.ExemptFromNamespaceChecks) MultiTargetedRestriction(org.dcache.auth.attributes.MultiTargetedRestriction) FsPath(diskCacheV111.util.FsPath) Restriction(org.dcache.auth.attributes.Restriction) Subjects(org.dcache.auth.Subjects) JwtSubPrincipal(org.dcache.auth.JwtSubPrincipal) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) GPlazmaAuthenticationPlugin(org.dcache.gplazma.plugins.GPlazmaAuthenticationPlugin) HttpClient(org.apache.http.client.HttpClient) Objects.requireNonNull(java.util.Objects.requireNonNull) Map(java.util.Map) Authorisation(org.dcache.auth.attributes.MultiTargetedRestriction.Authorisation) Splitter(com.google.common.base.Splitter) EnumSet(java.util.EnumSet) OidcSubjectPrincipal(org.dcache.auth.OidcSubjectPrincipal) BearerTokenCredential(org.dcache.auth.BearerTokenCredential) ImmutableSet(com.google.common.collect.ImmutableSet) Properties(java.util.Properties) Logger(org.slf4j.Logger) Preconditions.checkAuthentication(org.dcache.gplazma.util.Preconditions.checkAuthentication) Collection(java.util.Collection) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) Set(java.util.Set) IOException(java.io.IOException) JwtJtiPrincipal(org.dcache.auth.JwtJtiPrincipal) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) AuthenticationException(org.dcache.gplazma.AuthenticationException) List(java.util.List) Principal(java.security.Principal) Args(org.dcache.util.Args) Activity(org.dcache.auth.attributes.Activity) Optional(java.util.Optional) Collections(java.util.Collections) HttpClients(org.apache.http.impl.client.HttpClients) OidcSubjectPrincipal(org.dcache.auth.OidcSubjectPrincipal) JwtSubPrincipal(org.dcache.auth.JwtSubPrincipal) AuthenticationException(org.dcache.gplazma.AuthenticationException) ArrayList(java.util.ArrayList) BearerTokenCredential(org.dcache.auth.BearerTokenCredential) IOException(java.io.IOException) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) MultiTargetedRestriction(org.dcache.auth.attributes.MultiTargetedRestriction) Restriction(org.dcache.auth.attributes.Restriction) ExemptFromNamespaceChecks(org.dcache.auth.ExemptFromNamespaceChecks) JwtJtiPrincipal(org.dcache.auth.JwtJtiPrincipal) JwtSubPrincipal(org.dcache.auth.JwtSubPrincipal) OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal) OidcSubjectPrincipal(org.dcache.auth.OidcSubjectPrincipal) JwtJtiPrincipal(org.dcache.auth.JwtJtiPrincipal) Principal(java.security.Principal)

Example 4 with OpenIdGroupPrincipal

use of org.dcache.auth.OpenIdGroupPrincipal in project dcache by dCache.

the class GplazmaMultiMapFileTest method shouldPassWhenOpenIdGroupMapped.

@Test
public void shouldPassWhenOpenIdGroupMapped() throws Exception {
    givenConfig("oidcgrp:Users    group:desy");
    whenMapping(new OpenIdGroupPrincipal("Users"));
    assertThat(warnings, is(empty()));
    assertThat(mappedPrincipals, hasItem(new GroupNamePrincipal("desy")));
}
Also used : OpenIdGroupPrincipal(org.dcache.auth.OpenIdGroupPrincipal) GroupNamePrincipal(org.dcache.auth.GroupNamePrincipal) Test(org.junit.Test)

Aggregations

OpenIdGroupPrincipal (org.dcache.auth.OpenIdGroupPrincipal)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)2 Principal (java.security.Principal)2 ArrayList (java.util.ArrayList)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Splitter (com.google.common.base.Splitter)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 FsPath (diskCacheV111.util.FsPath)1 IOException (java.io.IOException)1 Instant (java.time.Instant)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 EnumSet (java.util.EnumSet)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Objects.requireNonNull (java.util.Objects.requireNonNull)1 Optional (java.util.Optional)1 Properties (java.util.Properties)1 Set (java.util.Set)1