mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Make client and IDP required when using federated client authentication (#43890)
Closes #43889 Signed-off-by: Alexander Schwartz <alexander.schwartz@gmx.net>
This commit is contained in:
parent
e84a1d6363
commit
52ba359cc3
@ -31,7 +31,7 @@ fips-mode-setup --enable
|
||||
== BouncyCastle library
|
||||
|
||||
{project_name} internally uses the BouncyCastle library for many cryptography utilities. Please note that the default version of the BouncyCastle library that shipped with {project_name} is not FIPS compliant;
|
||||
however, BouncyCastle also provides a FIPS validated version of its library. The FIPS validated BouncyCastle library is not shipped with {project_name} as
|
||||
however, BouncyCastle also provides a FIPS validated version of its library. The FIPS validated BouncyCastle library is not shipped with {project_name} as
|
||||
{project_name} cannot provide official support of it. Therefore, to run in FIPS compliant mode, you need to download BouncyCastle-FIPS bits and add them to the {project_name} distribution.
|
||||
When {project_name} executes in fips mode, it will use the BCFIPS bits instead of the default BouncyCastle bits, which achieves FIPS compliance.
|
||||
|
||||
@ -150,7 +150,7 @@ the older `pbkdf2-sha256` can log in because their passwords may be shorter than
|
||||
|
||||
* RSA keys of 1024 bits do not work (2048 is the minimum). This applies for keys used by the {project_name} realm itself (Realm keys from the `Keys` tab in the admin console), but also client keys and IDP keys
|
||||
|
||||
* HMAC SHA-XXX keys must be at least 112 bits (or 14 characters long). For example if you use OIDC clients with the client authentication `Signed Jwt with Client Secret` (or `client-secret-jwt` in
|
||||
* HMAC SHA-XXX keys must be at least 112 bits (or 14 characters long). For example if you use OIDC clients with the client authentication `Signed JWT with Client Secret` (or `client-secret-jwt` in
|
||||
the OIDC notation), then your client secrets should be at least 14 characters long. Note that for good security, it is recommended to use client secrets generated by the {project_name} server, which
|
||||
always fulfils this requirement.
|
||||
|
||||
|
||||
@ -943,6 +943,7 @@ addSamlProvider=Add SAML provider
|
||||
addSpiffeProvider=Add SPIFFE provider
|
||||
addKubernetesProvider=Add Kubernetes provider
|
||||
spiffeTrustDomain=SPIFFE Trust Domain
|
||||
spiffeTrustDomainHelp=Use a URL starting with 'spiffe://' followed by a domain name. For example, 'spiffe://acme.com'.
|
||||
spiffeBundleEndpoint=SPIFFE Bundle or OIDC JWKs endpoint
|
||||
kubernetesJWKSURL=Kubernetes JWKS URL
|
||||
kubernetesJWKSURLHelp=Use Kubernetes JWKS URL when accessing an external Kubernetes cluster. The JWKS endpoint must not require authentication
|
||||
|
||||
@ -18,6 +18,7 @@ export const SpiffeSettings = () => {
|
||||
<TextControl
|
||||
name="config.issuer"
|
||||
label={t("spiffeTrustDomain")}
|
||||
labelIcon={t("spiffeTrustDomainHelp")}
|
||||
rules={{
|
||||
required: t("required"),
|
||||
}}
|
||||
@ -26,6 +27,7 @@ export const SpiffeSettings = () => {
|
||||
<TextControl
|
||||
name="config.bundleEndpoint"
|
||||
label={t("spiffeBundleEndpoint")}
|
||||
labelIcon={t("Specify a URL starting with 'https://'.")}
|
||||
rules={{
|
||||
required: t("required"),
|
||||
}}
|
||||
|
||||
@ -16,6 +16,7 @@ import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
import org.keycloak.provider.ProviderConfigurationBuilder;
|
||||
import org.keycloak.services.resources.IdentityBrokerService;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -32,10 +33,22 @@ public class FederatedJWTClientAuthenticator extends AbstractClientAuthenticator
|
||||
public static final String JWT_CREDENTIAL_ISSUER_KEY = "jwt.credential.issuer";
|
||||
public static final String JWT_CREDENTIAL_SUBJECT_KEY = "jwt.credential.sub";
|
||||
|
||||
private static final List<ProviderConfigProperty> CLIENT_CONFIG = List.of(
|
||||
new ProviderConfigProperty(JWT_CREDENTIAL_ISSUER_KEY, "Identity provider", "Issuer of the client assertion", ProviderConfigProperty.STRING_TYPE, null),
|
||||
new ProviderConfigProperty(JWT_CREDENTIAL_SUBJECT_KEY, "Federated subject", "External clientId (subject)", ProviderConfigProperty.STRING_TYPE, null)
|
||||
);
|
||||
private static final List<ProviderConfigProperty> CLIENT_CONFIG =
|
||||
ProviderConfigurationBuilder.create()
|
||||
.property()
|
||||
.name(JWT_CREDENTIAL_ISSUER_KEY)
|
||||
.label("Identity provider")
|
||||
.helpText("Issuer of the client assertion. Use the alias of an identity provider set up in this realm.")
|
||||
.type(ProviderConfigProperty.STRING_TYPE)
|
||||
.required(true)
|
||||
.add()
|
||||
.property().name(JWT_CREDENTIAL_SUBJECT_KEY)
|
||||
.label("Federated subject")
|
||||
.helpText("External clientId (subject) as provided by the identity provider.")
|
||||
.type(ProviderConfigProperty.STRING_TYPE)
|
||||
.required(true)
|
||||
.add()
|
||||
.build();
|
||||
|
||||
private static final Set<String> SUPPORTED_ASSERTION_TYPES = Set.of(OAuth2Constants.CLIENT_ASSERTION_TYPE_JWT, SpiffeConstants.CLIENT_ASSERTION_TYPE);
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
|
||||
|
||||
@Override
|
||||
public String getDisplayType() {
|
||||
return "Signed Jwt";
|
||||
return "Signed JWT";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -167,7 +167,7 @@ public class JWTClientSecretAuthenticator extends AbstractClientAuthenticator {
|
||||
|
||||
@Override
|
||||
public String getDisplayType() {
|
||||
return "Signed Jwt with Client Secret";
|
||||
return "Signed JWT with Client Secret";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -161,8 +161,8 @@ public class InitialFlowsTest extends AbstractAuthenticationTest {
|
||||
|
||||
execs = new LinkedList<>();
|
||||
addExecInfo(execs, "Client Id and Secret", "client-secret", false, 0, 0, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 10);
|
||||
addExecInfo(execs, "Signed Jwt", "client-jwt", false, 0, 1, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 20);
|
||||
addExecInfo(execs, "Signed Jwt with Client Secret", "client-secret-jwt", false, 0, 2, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 30);
|
||||
addExecInfo(execs, "Signed JWT", "client-jwt", false, 0, 1, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 20);
|
||||
addExecInfo(execs, "Signed JWT with Client Secret", "client-secret-jwt", false, 0, 2, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 30);
|
||||
addExecInfo(execs, "X509 Certificate", "client-x509", false, 0, 3, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED}, 40);
|
||||
expected.add(new FlowExecutions(flow, execs));
|
||||
|
||||
|
||||
@ -82,13 +82,13 @@ public class ProvidersTest extends AbstractAuthenticationTest {
|
||||
List<Map<String, Object>> result = authMgmtResource.getClientAuthenticatorProviders();
|
||||
|
||||
List<Map<String, Object>> expected = new LinkedList<>();
|
||||
addClientAuthenticatorProviderInfo(expected, "client-jwt", "Signed Jwt",
|
||||
addClientAuthenticatorProviderInfo(expected, "client-jwt", "Signed JWT",
|
||||
"Validates client based on signed JWT issued by client and signed with the Client private key", false);
|
||||
addClientAuthenticatorProviderInfo(expected, "client-secret", "Client Id and Secret", "Validates client based on 'client_id' and " +
|
||||
"'client_secret' sent either in request parameters or in 'Authorization: Basic' header", true);
|
||||
addClientAuthenticatorProviderInfo(expected, "client-x509", "X509 Certificate",
|
||||
"Validates client based on a X509 Certificate", false);
|
||||
addClientAuthenticatorProviderInfo(expected, "client-secret-jwt", "Signed Jwt with Client Secret",
|
||||
addClientAuthenticatorProviderInfo(expected, "client-secret-jwt", "Signed JWT with Client Secret",
|
||||
"Validates client based on signed JWT issued by client and signed with the Client Secret", true);
|
||||
|
||||
compareProviders(expected, result);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user