Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.core.security.authc.oidc;
import org.apache.http.HttpHost;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.RealmSettings;
import org.elasticsearch.xpack.core.security.authc.support.DelegatedAuthorizationSettings;
import org.elasticsearch.xpack.core.ssl.SSLConfigurationSettings;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
public class OpenIdConnectRealmSettings {
private OpenIdConnectRealmSettings() {
}
public static final List SUPPORTED_SIGNATURE_ALGORITHMS =
org.elasticsearch.common.collect.List.of(
"HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512");
private static final List RESPONSE_TYPES = org.elasticsearch.common.collect.List.of(
"code", "id_token", "id_token token");
public static final List CLIENT_AUTH_METHODS = org.elasticsearch.common.collect.List.of(
"client_secret_basic", "client_secret_post", "client_secret_jwt");
public static final List SUPPORTED_CLIENT_AUTH_JWT_ALGORITHMS = org.elasticsearch.common.collect.List.of(
"HS256", "HS384", "HS512");
public static final String TYPE = "oidc";
public static final Setting.AffixSetting RP_CLIENT_ID
= RealmSettings.simpleString(TYPE, "rp.client_id", Setting.Property.NodeScope);
public static final Setting.AffixSetting RP_CLIENT_SECRET
= RealmSettings.secureString(TYPE, "rp.client_secret");
public static final Setting.AffixSetting RP_REDIRECT_URI
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.redirect_uri",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting RP_POST_LOGOUT_REDIRECT_URI
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.post_logout_redirect_uri",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting RP_RESPONSE_TYPE
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.response_type",
key -> Setting.simpleString(key, v -> {
if (RESPONSE_TYPES.contains(v) == false) {
throw new IllegalArgumentException(
"Invalid value [" + v + "] for [" + key + "]. Allowed values are " + RESPONSE_TYPES + "");
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting RP_SIGNATURE_ALGORITHM
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.signature_algorithm",
key -> new Setting<>(key, "RS256", Function.identity(), v -> {
if (SUPPORTED_SIGNATURE_ALGORITHMS.contains(v) == false) {
throw new IllegalArgumentException(
"Invalid value [" + v + "] for [" + key + "]. Allowed values are " + SUPPORTED_SIGNATURE_ALGORITHMS + "}]");
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting> RP_REQUESTED_SCOPES = Setting.affixKeySetting(
RealmSettings.realmSettingPrefix(TYPE), "rp.requested_scopes",
key -> Setting.listSetting(key, Collections.singletonList("openid"), Function.identity(), Setting.Property.NodeScope));
public static final Setting.AffixSetting RP_CLIENT_AUTH_METHOD
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.client_auth_method",
key -> new Setting<>(key, "client_secret_basic", Function.identity(), v -> {
if (CLIENT_AUTH_METHODS.contains(v) == false) {
throw new IllegalArgumentException(
"Invalid value [" + v + "] for [" + key + "]. Allowed values are " + CLIENT_AUTH_METHODS + "}]");
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting RP_CLIENT_AUTH_JWT_SIGNATURE_ALGORITHM
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "rp.client_auth_jwt_signature_algorithm",
key -> new Setting<>(key, "HS384", Function.identity(), v -> {
if (SUPPORTED_CLIENT_AUTH_JWT_ALGORITHMS.contains(v) == false) {
throw new IllegalArgumentException(
"Invalid value [" + v + "] for [" + key + "]. Allowed values are " + SUPPORTED_CLIENT_AUTH_JWT_ALGORITHMS + "}]");
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting OP_AUTHORIZATION_ENDPOINT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "op.authorization_endpoint",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting OP_TOKEN_ENDPOINT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "op.token_endpoint",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting OP_USERINFO_ENDPOINT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "op.userinfo_endpoint",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting OP_ENDSESSION_ENDPOINT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "op.endsession_endpoint",
key -> Setting.simpleString(key, v -> {
try {
new URI(v);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid value [" + v + "] for [" + key + "]. Not a valid URI.", e);
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting OP_ISSUER
= RealmSettings.simpleString(TYPE, "op.issuer", Setting.Property.NodeScope);
public static final Setting.AffixSetting OP_JWKSET_PATH
= RealmSettings.simpleString(TYPE, "op.jwkset_path", Setting.Property.NodeScope);
public static final Setting.AffixSetting ALLOWED_CLOCK_SKEW
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "allowed_clock_skew",
key -> Setting.timeSetting(key, TimeValue.timeValueSeconds(60), Setting.Property.NodeScope));
public static final Setting.AffixSetting POPULATE_USER_METADATA = Setting.affixKeySetting(
RealmSettings.realmSettingPrefix(TYPE), "populate_user_metadata",
key -> Setting.boolSetting(key, true, Setting.Property.NodeScope));
private static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueSeconds(5);
public static final Setting.AffixSetting HTTP_CONNECT_TIMEOUT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.connect_timeout",
key -> Setting.timeSetting(key, DEFAULT_TIMEOUT, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_CONNECTION_READ_TIMEOUT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.connection_read_timeout",
key -> Setting.timeSetting(key, DEFAULT_TIMEOUT, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_SOCKET_TIMEOUT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.socket_timeout",
key -> Setting.timeSetting(key, DEFAULT_TIMEOUT, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_MAX_CONNECTIONS
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.max_connections",
key -> Setting.intSetting(key, 200, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_MAX_ENDPOINT_CONNECTIONS
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.max_endpoint_connections",
key -> Setting.intSetting(key, 200, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_PROXY_HOST
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.proxy.host",
key -> Setting.simpleString(key, new Setting.Validator() {
@Override
public void validate(String value) {
// There is no point in validating the hostname in itself without the scheme and port
}
@Override
public void validate(String value, Map, Object> settings) {
final String namespace = HTTP_PROXY_HOST.getNamespace(HTTP_PROXY_HOST.getConcreteSetting(key));
final Setting portSetting = HTTP_PROXY_PORT.getConcreteSettingForNamespace(namespace);
final Integer port = (Integer) settings.get(portSetting);
final Setting schemeSetting = HTTP_PROXY_SCHEME.getConcreteSettingForNamespace(namespace);
final String scheme = (String) settings.get(schemeSetting);
try {
new HttpHost(value, port, scheme);
} catch (Exception e) {
throw new IllegalArgumentException("HTTP host for hostname [" + value + "] (from [" + key + "])," +
" port [" + port + "] (from [" + portSetting.getKey() + "]) and " +
"scheme [" + scheme + "] (from ([" + schemeSetting.getKey() + "]) is invalid");
}
}
@Override
public Iterator> settings() {
final String namespace = HTTP_PROXY_HOST.getNamespace(HTTP_PROXY_HOST.getConcreteSetting(key));
final List> settings = Arrays.asList(HTTP_PROXY_PORT.getConcreteSettingForNamespace(namespace),
HTTP_PROXY_SCHEME.getConcreteSettingForNamespace(namespace));
return settings.iterator();
}
}, Setting.Property.NodeScope));
public static final Setting.AffixSetting HTTP_PROXY_PORT
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.proxy.port",
key -> Setting.intSetting(key, 80, 1, 65535, Setting.Property.NodeScope), () -> HTTP_PROXY_HOST);
public static final Setting.AffixSetting HTTP_PROXY_SCHEME
= Setting.affixKeySetting(RealmSettings.realmSettingPrefix(TYPE), "http.proxy.scheme",
key -> Setting.simpleString(key, "http", value -> {
if (value.equals("http") == false && value.equals("https") == false) {
throw new IllegalArgumentException("Invalid value [" + value + "] for [" + key + "]. Only `http` or `https` are allowed.");
}
}, Setting.Property.NodeScope));
public static final ClaimSetting PRINCIPAL_CLAIM = new ClaimSetting("principal");
public static final ClaimSetting GROUPS_CLAIM = new ClaimSetting("groups");
public static final ClaimSetting NAME_CLAIM = new ClaimSetting("name");
public static final ClaimSetting DN_CLAIM = new ClaimSetting("dn");
public static final ClaimSetting MAIL_CLAIM = new ClaimSetting("mail");
public static Set> getSettings() {
final Set> set = Sets.newHashSet(
RP_CLIENT_ID, RP_REDIRECT_URI, RP_RESPONSE_TYPE, RP_REQUESTED_SCOPES, RP_CLIENT_SECRET, RP_SIGNATURE_ALGORITHM,
RP_POST_LOGOUT_REDIRECT_URI, RP_CLIENT_AUTH_METHOD, RP_CLIENT_AUTH_JWT_SIGNATURE_ALGORITHM, OP_AUTHORIZATION_ENDPOINT,
OP_TOKEN_ENDPOINT, OP_USERINFO_ENDPOINT, OP_ENDSESSION_ENDPOINT, OP_ISSUER, OP_JWKSET_PATH,
POPULATE_USER_METADATA, HTTP_CONNECT_TIMEOUT, HTTP_CONNECTION_READ_TIMEOUT,
HTTP_SOCKET_TIMEOUT, HTTP_MAX_CONNECTIONS, HTTP_MAX_ENDPOINT_CONNECTIONS, HTTP_PROXY_HOST, HTTP_PROXY_PORT,
HTTP_PROXY_SCHEME, ALLOWED_CLOCK_SKEW);
set.addAll(DelegatedAuthorizationSettings.getSettings(TYPE));
set.addAll(RealmSettings.getStandardSettings(TYPE));
set.addAll(SSLConfigurationSettings.getRealmSettings(TYPE));
set.addAll(PRINCIPAL_CLAIM.settings());
set.addAll(GROUPS_CLAIM.settings());
set.addAll(DN_CLAIM.settings());
set.addAll(NAME_CLAIM.settings());
set.addAll(MAIL_CLAIM.settings());
return set;
}
/**
* The OIDC realm offers a number of settings that rely on claim values that are populated by the OP in the ID Token or the User Info
* response.
* Each claim has 2 settings:
*
*
The name of the OpenID Connect claim to use
*
An optional java pattern (regex) to apply to that claim value in order to extract the substring that should be used.
*
* For example, the Elasticsearch User Principal could be configured to come from the OpenID Connect standard claim "email",
* and extract only the local-part of the user's email address (i.e. the name before the '@').
* This class encapsulates those 2 settings.
*/
public static final class ClaimSetting {
public static final String CLAIMS_PREFIX = "claims.";
public static final String CLAIM_PATTERNS_PREFIX = "claim_patterns.";
private final Setting.AffixSetting claim;
private final Setting.AffixSetting pattern;
public ClaimSetting(String name) {
claim = RealmSettings.simpleString(TYPE, CLAIMS_PREFIX + name, Setting.Property.NodeScope);
pattern = RealmSettings.simpleString(TYPE, CLAIM_PATTERNS_PREFIX + name, Setting.Property.NodeScope);
}
public Collection> settings() {
return Arrays.asList(getClaim(), getPattern());
}
public String name(RealmConfig config) {
return getClaim().getConcreteSettingForNamespace(config.name()).getKey();
}
public Setting.AffixSetting getClaim() {
return claim;
}
public Setting.AffixSetting getPattern() {
return pattern;
}
}
}