Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guides/server/hostname.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The result of this configuration is that you can continue to access {project_nam

== Using a reverse proxy

When a proxy is in use, the `proxy-headers` should be set. Depending on the hostname settings, some or all of the URL, may be dynamically determined.
When a proxy is forwarding http or reencrypted TLS requests, the `proxy-headers` option should be set. Depending on the hostname settings, some or all of the URL, may be dynamically determined.

WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Misconfiguration will leave {project_name} exposed to security vulnerabilities.

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/server/reverseproxy.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Distributed environments frequently require the use of a reverse proxy. {project
* `forwarded` enables parsing of the `Forwarded` header as per https://www.rfc-editor.org/rfc/rfc7239.html[RFC7239].
* `xforwarded` enables parsing of non-standard `X-Forwarded-*` headers, such as `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host`, and `X-Forwarded-Port`.

NOTE: If you are using a reverse proxy and do not set the `proxy-headers` option, then by default you will see 403 Forbidden responses to requests via the proxy that perform origin checking.
NOTE: If you are using a reverse proxy for anything other than https passthrough and do not set the `proxy-headers` option, then by default you will see 403 Forbidden responses to requests via the proxy that perform origin checking.

For example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import org.keycloak.quarkus.runtime.Messages;
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
import org.keycloak.quarkus.runtime.configuration.mappers.HostnameV2PropertyMappers;
import org.keycloak.quarkus.runtime.configuration.mappers.HttpPropertyMappers;
import org.keycloak.url.HostnameV2ProviderFactory;

import java.util.EnumSet;
import java.util.List;
Expand All @@ -42,6 +44,7 @@ public void run() {
doBeforeRun();
CommandLine cmd = spec.commandLine();
HttpPropertyMappers.validateConfig();
HostnameV2PropertyMappers.validateConfig();
validateConfig();

if (ConfigArgsConfigSource.getAllCliArgs().contains(OPTIMIZED_BUILD_OPTION_LONG) && !wasBuildEverRun()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package org.keycloak.quarkus.runtime.configuration.mappers;

import org.keycloak.common.Profile;
import org.keycloak.config.HostnameV2Options;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import org.jboss.logging.Logger;
import org.keycloak.common.Profile;
import org.keycloak.config.HostnameV2Options;
import org.keycloak.quarkus.runtime.configuration.Configuration;

final class HostnameV2PropertyMappers {
public final class HostnameV2PropertyMappers {

private static final Logger LOGGER = Logger.getLogger(PropertyMappers.class);
private static final List<String> REMOVED_OPTIONS = Arrays.asList("hostname-admin-url", "hostname-path", "hostname-port", "hostname-strict-backchannel", "hostname-url", "proxy", "hostname-strict-https");

private HostnameV2PropertyMappers(){}

Expand All @@ -28,5 +35,13 @@ public static PropertyMapper<?>[] getHostnamePropertyMappers() {
.map(b -> b.isEnabled(() -> Profile.isFeatureEnabled(Profile.Feature.HOSTNAME_V2), "hostname:v2 feature is enabled").build())
.toArray(s -> new PropertyMapper<?>[s]);
}

public static void validateConfig() {
List<String> inUse = REMOVED_OPTIONS.stream().filter(s -> Configuration.getOptionalKcValue(s).isPresent()).toList();

if (!inUse.isEmpty()) {
LOGGER.errorf("Hostname v1 options %s are still in use, please review your configuration", inUse);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Response preCheck(@QueryParam("client_id") String clientId, @QueryParam("
if (validWebOrigins.contains("*") || validWebOrigins.contains(origin)) {
return Response.noContent().build();
}
logger.debugf("client %s does not allow origin=%s for requestOrigin=%s (as determined by hostname settings), init will return a 403", clientId, origin, requestOrigin);
logger.debugf("client %s does not allow origin=%s for requestOrigin=%s (as determined by the proxy-header setting), init will return a 403", clientId, origin, requestOrigin);
} else {
logger.debugf("client %s does not exist or not enabled, init will return a 403", clientId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Arrays;
import java.util.Optional;

import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.common.Profile;
import org.keycloak.models.KeycloakSession;
Expand All @@ -32,6 +33,9 @@
* @author Vaclav Muzikar <[email protected]>
*/
public class HostnameV2ProviderFactory implements HostnameProviderFactory, EnvironmentDependentProviderFactory {

private static final Logger LOGGER = Logger.getLogger(HostnameV2ProviderFactory.class);

private static final String INVALID_HOSTNAME = "Provided hostname is neither a plain hostname nor a valid URL";
private String hostname;
private URI hostnameUrl;
Expand All @@ -41,14 +45,15 @@ public class HostnameV2ProviderFactory implements HostnameProviderFactory, Envir
@Override
public void init(Config.Scope config) {
// Strict mode is used just for enforcing that hostname is set
Boolean strictMode = config.getBoolean("hostname-strict", false);
boolean strictMode = config.getBoolean("hostname-strict", false);

String hostnameRaw = config.get("hostname");
if (strictMode && hostnameRaw == null) {
throw new IllegalArgumentException("hostname is not configured; either configure hostname, or set hostname-strict to false");
} else if (hostnameRaw != null && !strictMode) {
// We might not need this validation as it doesn't matter in this case if strict is true or false. It's just for consistency – hostname XOR !strict.
// throw new IllegalArgumentException("hostname is configured, hostname-strict must be set to true");
LOGGER.info("If hostanme is specified, hostname-strict is effectively ignored");
}

// Set hostname, can be either a full URL, or just hostname
Expand Down