Search in sources :

Example 1 with AuthenticationException

use of org.dcache.gplazma.AuthenticationException in project dcache by dCache.

the class QueryUserInfoEndpoint method identityProviders.

private Collection<IdentityProvider> identityProviders(String token) throws AuthenticationException {
    if (JsonWebToken.isCompatibleFormat(token)) {
        try {
            JsonWebToken jwt = new JsonWebToken(token);
            Optional<String> iss = jwt.getPayloadString("iss");
            if (iss.isPresent()) {
                try {
                    URI issuer = new URI(iss.get());
                    IdentityProvider ip = providersByIssuer.get(issuer);
                    checkAuthentication(ip != null, "JWT with unknown \"iss\" claim");
                    LOG.debug("Discovered token is JWT issued by {}", ip.getName());
                    return Collections.singleton(ip);
                } catch (URISyntaxException e) {
                    LOG.debug("Bad \"iss\" claim \"{}\": {}", iss.get(), e.toString());
                    throw new AuthenticationException("Bad \"iss\" claim in JWT");
                }
            }
        } catch (IOException e) {
            LOG.debug("Failed to parse JWT: {}", e.toString());
            throw new AuthenticationException("Bad JWT");
        }
    }
    return providersByIssuer.values();
}
Also used : AuthenticationException(org.dcache.gplazma.AuthenticationException) IdentityProvider(org.dcache.gplazma.oidc.IdentityProvider) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) URI(java.net.URI)

Example 2 with AuthenticationException

use of org.dcache.gplazma.AuthenticationException in project dcache by dCache.

the class QueryUserInfoEndpoint method extract.

@Override
public ExtractResult extract(String token) throws AuthenticationException {
    Stopwatch userinfoLookupTiming = Stopwatch.createStarted();
    List<LookupResult> allResults;
    try {
        allResults = userInfoCache.get(token);
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        Throwables.throwIfInstanceOf(cause, AuthenticationException.class);
        Throwables.throwIfUnchecked(cause);
        if (cause instanceof InterruptedException) {
            throw new AuthenticationException("Shutting down");
        }
        throw new RuntimeException("Unexpected exception", e);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Doing user-info lookup against {} OPs took {}", allResults.size(), TimeUtils.describe(userinfoLookupTiming.elapsed()).orElse("no time"));
    }
    List<LookupResult> successfulResults = allResults.stream().filter(LookupResult::isSuccess).collect(Collectors.toList());
    if (successfulResults.isEmpty()) {
        if (allResults.size() == 1) {
            LookupResult result = allResults.get(0);
            throw new AuthenticationException("OpenId Validation failed for " + result.getIdentityProvider().getName() + ": " + result.getError());
        } else {
            String randomId = randomId();
            String errors = allResults.stream().map(r -> "[" + r.getIdentityProvider().getName() + ": " + r.getError() + "]").collect(Collectors.joining(", "));
            LOG.warn("OpenId Validation Failure ({}): {}", randomId, errors);
            throw new AuthenticationException("OpenId Validation Failed check [log entry #" + randomId + "]");
        }
    }
    if (successfulResults.size() > 1) {
        String names = successfulResults.stream().map(LookupResult::getIdentityProvider).map(IdentityProvider::getName).collect(Collectors.joining(", "));
        LOG.warn("Multiple OpenID-Connect endpoints accepted access token: {}", names);
        throw new AuthenticationException("Multiple OPs accepted token.");
    }
    var result = successfulResults.get(0);
    return new ExtractResult(result.getIdentityProvider(), result.getClaims());
}
Also used : LoadingCache(com.google.common.cache.LoadingCache) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Stopwatch(com.google.common.base.Stopwatch) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) ArrayList(java.util.ArrayList) ExtractResult(org.dcache.gplazma.oidc.ExtractResult) ListenableFutureTask(com.google.common.util.concurrent.ListenableFutureTask) Collectors.toMap(java.util.stream.Collectors.toMap) Duration(java.time.Duration) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Objects.requireNonNull(java.util.Objects.requireNonNull) JsonNode(com.fasterxml.jackson.databind.JsonNode) URI(java.net.URI) TimeUtils(org.dcache.util.TimeUtils) JsonHttpClient(org.dcache.gplazma.oidc.helpers.JsonHttpClient) ExecutorService(java.util.concurrent.ExecutorService) JsonNodeType(com.fasterxml.jackson.databind.node.JsonNodeType) Properties(java.util.Properties) Logger(org.slf4j.Logger) Preconditions.checkAuthentication(org.dcache.gplazma.util.Preconditions.checkAuthentication) PropertiesUtils.asInt(org.dcache.gplazma.oidc.PropertiesUtils.asInt) TokenProcessor(org.dcache.gplazma.oidc.TokenProcessor) Collection(java.util.Collection) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) Throwables(com.google.common.base.Throwables) Set(java.util.Set) IOException(java.io.IOException) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) AuthenticationException(org.dcache.gplazma.AuthenticationException) CacheLoader(com.google.common.cache.CacheLoader) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Futures(com.google.common.util.concurrent.Futures) Base64(java.util.Base64) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) Entry(java.util.Map.Entry) Optional(java.util.Optional) CacheBuilder(com.google.common.cache.CacheBuilder) Collections(java.util.Collections) IdentityProvider(org.dcache.gplazma.oidc.IdentityProvider) BoundedCachedExecutor(org.dcache.util.BoundedCachedExecutor) AuthenticationException(org.dcache.gplazma.AuthenticationException) Stopwatch(com.google.common.base.Stopwatch) ExecutionException(java.util.concurrent.ExecutionException) ExtractResult(org.dcache.gplazma.oidc.ExtractResult)

Example 3 with AuthenticationException

use of org.dcache.gplazma.AuthenticationException in project dcache by dCache.

the class Nis method session.

@Override
public void session(Set<Principal> authorizedPrincipals, Set<Object> attrib) throws AuthenticationException {
    Principal principal = find(authorizedPrincipals, instanceOf(UserNamePrincipal.class), null);
    checkAuthentication(principal != null, "no username principal");
    try {
        Attributes userAttr = _ctx.getAttributes(NISMAP_PASSWORD_BY_NAME + "/" + principal.getName());
        attrib.add(new HomeDirectory((String) userAttr.get(HOME_DIR_ATTRIBUTE).get()));
        attrib.add(new RootDirectory("/"));
    } catch (NamingException e) {
        throw new AuthenticationException("no mapping: " + e.getMessage(), e);
    }
}
Also used : UserNamePrincipal(org.dcache.auth.UserNamePrincipal) HomeDirectory(org.dcache.auth.attributes.HomeDirectory) AuthenticationException(org.dcache.gplazma.AuthenticationException) BasicAttributes(javax.naming.directory.BasicAttributes) Attributes(javax.naming.directory.Attributes) RootDirectory(org.dcache.auth.attributes.RootDirectory) NamingException(javax.naming.NamingException) GroupNamePrincipal(org.dcache.auth.GroupNamePrincipal) GidPrincipal(org.dcache.auth.GidPrincipal) UserNamePrincipal(org.dcache.auth.UserNamePrincipal) Principal(java.security.Principal) UidPrincipal(org.dcache.auth.UidPrincipal)

Example 4 with AuthenticationException

use of org.dcache.gplazma.AuthenticationException in project dcache by dCache.

the class Nis method map.

@Override
public void map(Set<Principal> principals) throws AuthenticationException {
    boolean mapped;
    Principal principal = find(principals, instanceOf(UserNamePrincipal.class), null);
    checkAuthentication(principal != null, "no username principal");
    try {
        Attributes userAttr = _ctx.getAttributes(NISMAP_PASSWORD_BY_NAME + "/" + principal.getName());
        principals.add(new UidPrincipal((String) userAttr.get(UID_NUMBER_ATTRIBUTE).get()));
        principals.add(new GidPrincipal((String) userAttr.get(GID_NUMBER_ATTRIBUTE).get(), true));
        NamingEnumeration<SearchResult> groupResult = _ctx.search(NISMAP_GROUP_BY_NAME, new BasicAttributes(MEMBER_UID_ATTRIBUTE, principal.getName()));
        mapped = true;
        while (groupResult.hasMore()) {
            SearchResult result = groupResult.next();
            principals.add(new GidPrincipal((String) result.getAttributes().get(GID_NUMBER_ATTRIBUTE).get(), false));
        }
    } catch (NamingException e) {
        LOGGER.debug("Failed to get mapping: {}", e.toString());
        throw new AuthenticationException("no mapping: " + e.getMessage(), e);
    }
    checkAuthentication(mapped, "no matching principal");
}
Also used : UserNamePrincipal(org.dcache.auth.UserNamePrincipal) BasicAttributes(javax.naming.directory.BasicAttributes) AuthenticationException(org.dcache.gplazma.AuthenticationException) UidPrincipal(org.dcache.auth.UidPrincipal) BasicAttributes(javax.naming.directory.BasicAttributes) Attributes(javax.naming.directory.Attributes) SearchResult(javax.naming.directory.SearchResult) NamingException(javax.naming.NamingException) GroupNamePrincipal(org.dcache.auth.GroupNamePrincipal) GidPrincipal(org.dcache.auth.GidPrincipal) UserNamePrincipal(org.dcache.auth.UserNamePrincipal) Principal(java.security.Principal) UidPrincipal(org.dcache.auth.UidPrincipal) GidPrincipal(org.dcache.auth.GidPrincipal)

Example 5 with AuthenticationException

use of org.dcache.gplazma.AuthenticationException in project dcache by dCache.

the class BanFilePlugin method loadConfigIfNeeded.

/**
 * Create a list of principals from the source file. The empty lines and comments, i.e., lines
 * starting with '#' are ignored. It expects the file to be of the format: alias <alias>=<full
 * qualified classname> ban <full qualified classname or alias>:<principal string> e.g., alias
 * username=org.dcache.auth.UserNamePrincipal ban username:Someuser or ban
 * org.dcache.auth.UserNamePrincipal:Someuser
 *
 * @return a set of banned principals
 */
private synchronized Set<Principal> loadConfigIfNeeded() throws AuthenticationException {
    try {
        if (bannedPrincipals == null || lastFileRead.isBefore(Files.readAttributes(configFile, BasicFileAttributes.class).lastModifiedTime().toInstant())) {
            // alias -> value, like uid=org.dcache.auth.UidPrincipal
            Map<String, String> aliases = new HashMap<>();
            // class/alias -> value, like uid:123 or org.dcache.auth.UidPrincipal:123
            Map<String, String> bans = new HashMap<>();
            // group all 'alias' and all 'ban' records, skip comments and empty lines
            Map<String, List<String>> config = loadConfigLines().stream().map(String::strip).filter(not(String::isEmpty)).filter(l -> l.charAt(0) != '#').collect(Collectors.groupingBy(l -> l.split("\\s")[0]));
            // process aliases  as they might be used in the next step
            List<String> configuredAliases = config.remove("alias");
            if (configuredAliases != null) {
                configuredAliases.forEach(a -> {
                    Matcher m = ALIAS_PATTERN.matcher(a);
                    if (!m.matches()) {
                        throw new IllegalArgumentException("Bad alias line format: '" + a + "', expected 'alias <alias>=<class>'");
                    }
                    String alias = m.group(1);
                    String clazz = m.group(2);
                    aliases.put(alias, clazz);
                });
            }
            // process ban records. substitute aliases, if needed
            List<String> configuredBans = config.remove("ban");
            if (configuredBans != null) {
                configuredBans.forEach(a -> {
                    Matcher m = BAN_PATTERN.matcher(a);
                    if (!m.matches()) {
                        throw new IllegalArgumentException("Bad ban line format: '" + a + "', expected 'ban <classOrAlias>:<value>'");
                    }
                    String clazz = m.group(1);
                    String value = m.group(2);
                    bans.put(aliases.getOrDefault(clazz, clazz), value);
                });
            }
            // any other key is an error
            if (!config.isEmpty()) {
                String badLines = config.values().stream().flatMap(List::stream).collect(Collectors.joining(",", "[", "]"));
                throw new IllegalArgumentException("Line has bad format: '" + badLines + "', expected '[alias|ban] <key>:<value>'");
            }
            // construct lines suitable for Subjects.principalsFromArgs
            // class:value or shortname:value
            List<String> bannedNames = bans.entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).collect(Collectors.toList());
            bannedPrincipals = Subjects.principalsFromArgs(bannedNames);
            lastFileRead = Instant.now();
        }
    } catch (IOException e) {
        throw new AuthenticationException(e);
    }
    return bannedPrincipals;
}
Also used : Properties(java.util.Properties) Files(java.nio.file.Files) Subjects(org.dcache.auth.Subjects) Set(java.util.Set) IOException(java.io.IOException) HashMap(java.util.HashMap) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) AuthenticationException(org.dcache.gplazma.AuthenticationException) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) List(java.util.List) Principal(java.security.Principal) Matcher(java.util.regex.Matcher) Map(java.util.Map) Pattern(java.util.regex.Pattern) Predicate.not(java.util.function.Predicate.not) Path(java.nio.file.Path) Collections(java.util.Collections) HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) AuthenticationException(org.dcache.gplazma.AuthenticationException) List(java.util.List) IOException(java.io.IOException)

Aggregations

AuthenticationException (org.dcache.gplazma.AuthenticationException)30 Principal (java.security.Principal)12 IOException (java.io.IOException)7 GidPrincipal (org.dcache.auth.GidPrincipal)7 UserNamePrincipal (org.dcache.auth.UserNamePrincipal)7 List (java.util.List)6 Set (java.util.Set)6 Properties (java.util.Properties)5 Collectors (java.util.stream.Collectors)5 GroupNamePrincipal (org.dcache.auth.GroupNamePrincipal)5 UidPrincipal (org.dcache.auth.UidPrincipal)5 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)4 ArrayList (java.util.ArrayList)4 Map (java.util.Map)4 NamingException (javax.naming.NamingException)4 Attributes (javax.naming.directory.Attributes)4 BasicAttributes (javax.naming.directory.BasicAttributes)4 UserPrincipal (com.sun.security.auth.UserPrincipal)3 Instant (java.time.Instant)3 Collections (java.util.Collections)3