Added KERBEROS feature. Disable it when running tests on FIPS
closes #14966
This commit is contained in:
parent
9176308d79
commit
a804400c84
27 changed files with 212 additions and 28 deletions
|
@ -22,6 +22,7 @@ import org.keycloak.common.profile.ProfileConfigResolver;
|
|||
import org.keycloak.common.profile.ProfileException;
|
||||
import org.keycloak.common.profile.PropertiesFileProfileConfigResolver;
|
||||
import org.keycloak.common.profile.PropertiesProfileConfigResolver;
|
||||
import org.keycloak.common.util.KerberosJdkProvider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -81,6 +82,9 @@ public class Profile {
|
|||
|
||||
STEP_UP_AUTHENTICATION("Step-up Authentication", Type.DEFAULT),
|
||||
|
||||
// Check if kerberos is available in underlying JVM and auto-detect if feature should be enabled or disabled by default based on that
|
||||
KERBEROS("Kerberos", KerberosJdkProvider.getProvider().isKerberosAvailable() ? Type.DEFAULT : Type.DISABLED_BY_DEFAULT),
|
||||
|
||||
RECOVERY_CODES("Recovery codes", Type.PREVIEW),
|
||||
|
||||
UPDATE_EMAIL("Update Email Action", Type.PREVIEW),
|
||||
|
|
|
@ -20,6 +20,8 @@ package org.keycloak.common.util;
|
|||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.GSSName;
|
||||
import org.ietf.jgss.Oid;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
@ -31,9 +33,11 @@ import java.io.File;
|
|||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -44,6 +48,8 @@ import java.util.Set;
|
|||
*/
|
||||
public abstract class KerberosJdkProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(KerberosJdkProvider.class);
|
||||
|
||||
public abstract Configuration createJaasConfigurationForServer(String keytab, String serverPrincipal, boolean debug);
|
||||
public abstract Configuration createJaasConfigurationForUsernamePasswordLogin(boolean debug);
|
||||
|
||||
|
@ -55,6 +61,20 @@ public abstract class KerberosJdkProvider {
|
|||
return kerberosTicketToGSSCredential(kerberosTicket, GSSCredential.DEFAULT_LIFETIME, GSSCredential.INITIATE_ONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if Kerberos (GSS API) is available in underlying JDK and it is possible to use it. False otherwise
|
||||
*/
|
||||
public boolean isKerberosAvailable() {
|
||||
GSSManager gssManager = GSSManager.getInstance();
|
||||
List<Oid> supportedMechs = Arrays.asList(gssManager.getMechs());
|
||||
if (supportedMechs.contains(KerberosConstants.KRB5_OID)) {
|
||||
return true;
|
||||
} else {
|
||||
logger.warnf("Kerberos feature not supported by JDK. Check security providers for your JDK in java.security. Supported mechanisms: %s", supportedMechs);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Actually can use same on both JDKs
|
||||
public GSSCredential kerberosTicketToGSSCredential(KerberosTicket kerberosTicket, final int lifetime, final int usage) {
|
||||
try {
|
||||
|
|
18
docs/fips.md
18
docs/fips.md
|
@ -97,6 +97,24 @@ When starting server at startup, you can check that startup log contains `KC` pr
|
|||
KC(BCFIPS version 1.000203 Approved Mode) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider,
|
||||
```
|
||||
|
||||
Other considerations
|
||||
--------------------
|
||||
#### SAML and Kerberos
|
||||
In order to have SAML working, there is a need to have `XMLDSig` security provider to be available in your `JAVA_HOME/conf/security/java.security`.
|
||||
In order to have Kerberos working, there is a need to have `SunJGSS` security provider available. In FIPS enabled RHEL 8.6 in OpenJDK 17.0.5, these
|
||||
security providers are not by default in the `java.security`, which means that they effectively cannot work.
|
||||
|
||||
To have SAML working, you can manually add the provider into `java.security` into the list fips providers. For example add the line like:
|
||||
```
|
||||
fips.provider.7=XMLDSig
|
||||
```
|
||||
Adding this security provider should be fine as in fact it is FIPS compliant and likely will be added by default in the future OpenJDK micro version.
|
||||
Details: https://bugzilla.redhat.com/show_bug.cgi?id=1940064
|
||||
|
||||
For Kerberos, there are few more things to be done to have security provider FIPS compliant. Hence it is not recommended to add security provider
|
||||
if you want to be FIPS compliant. The `KERBEROS` feature is disabled by default in Keycloak when it is executed on this platform and when security provider is not
|
||||
available. Details: https://bugzilla.redhat.com/show_bug.cgi?id=2051628
|
||||
|
||||
Run the CLI on the FIPS host
|
||||
----------------------------
|
||||
In case you want to run Client Registration CLI (`kcreg.sh/bat` script) or Admin CLI (`kcadm.sh/bat` script), it is needed
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.federation.kerberos;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.federation.kerberos.impl.KerberosServerSubjectAuthenticator;
|
||||
|
@ -29,6 +30,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
import org.keycloak.provider.ProviderConfigurationBuilder;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
@ -45,7 +47,7 @@ import java.util.List;
|
|||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class KerberosFederationProviderFactory implements UserStorageProviderFactory<KerberosFederationProvider> {
|
||||
public class KerberosFederationProviderFactory implements UserStorageProviderFactory<KerberosFederationProvider>, EnvironmentDependentProviderFactory {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(KerberosFederationProviderFactory.class);
|
||||
public static final String PROVIDER_NAME = "kerberos";
|
||||
|
@ -60,6 +62,11 @@ public class KerberosFederationProviderFactory implements UserStorageProviderFac
|
|||
return PROVIDER_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return Profile.isFeatureEnabled(Profile.Feature.KERBEROS);
|
||||
}
|
||||
|
||||
protected static final List<ProviderConfigProperty> configProperties;
|
||||
|
||||
static {
|
||||
|
|
|
@ -46,14 +46,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -46,14 +46,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -69,14 +69,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -69,14 +69,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -127,14 +127,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -127,14 +127,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -75,14 +75,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -75,14 +75,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -133,14 +133,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -133,14 +133,14 @@ Feature:
|
|||
--features <feature> Enables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: account-api,
|
||||
account2, admin, admin-api, admin-fine-grained-authz, admin2, authorization,
|
||||
ciba, client-policies, client-secret-rotation, declarative-user-profile,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, map-storage,
|
||||
docker, dynamic-scopes, impersonation, js-adapter, kerberos, map-storage,
|
||||
openshift-integration, par, preview, recovery-codes, scripts,
|
||||
step-up-authentication, token-exchange, update-email, web-authn.
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ import java.util.Map;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SpnegoAuthenticator extends AbstractUsernameFormAuthenticator implements Authenticator{
|
||||
public static final String KERBEROS_DISABLED = "kerberos_disabled";
|
||||
private static final Logger logger = Logger.getLogger(SpnegoAuthenticator.class);
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,10 +20,12 @@ package org.keycloak.authentication.authenticators.browser;
|
|||
import org.keycloak.Config;
|
||||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -32,7 +34,7 @@ import java.util.List;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SpnegoAuthenticatorFactory implements AuthenticatorFactory {
|
||||
public class SpnegoAuthenticatorFactory implements AuthenticatorFactory, EnvironmentDependentProviderFactory {
|
||||
|
||||
public static final String PROVIDER_ID = "auth-spnego";
|
||||
public static final SpnegoAuthenticator SINGLETON = new SpnegoAuthenticator();
|
||||
|
@ -98,4 +100,8 @@ public class SpnegoAuthenticatorFactory implements AuthenticatorFactory {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return Profile.isFeatureEnabled(Profile.Feature.KERBEROS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.keycloak.authentication.authenticators.browser;
|
||||
|
||||
|
||||
import org.keycloak.authentication.AuthenticationFlowContext;
|
||||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
/**
|
||||
* Factory used only when KERBEROS feature is disabled. This exists due the KERBEROS authenticator is added by default to realm browser flow (even if DISABLED by default)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class SpnegoDisabledAuthenticatorFactory extends SpnegoAuthenticatorFactory implements AuthenticatorFactory {
|
||||
|
||||
@Override
|
||||
public Authenticator create(KeycloakSession session) {
|
||||
return new SpnegoDisabledAuthenticator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpText() {
|
||||
return "DISABLED. Please enable Kerberos feature and make sure Kerberos available in your platform. Initiates the SPNEGO protocol. Most often used with Kerberos.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
|
||||
return new AuthenticationExecutionModel.Requirement[]{ AuthenticationExecutionModel.Requirement.DISABLED };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return !Profile.isFeatureEnabled(Profile.Feature.KERBEROS);
|
||||
}
|
||||
|
||||
public static class SpnegoDisabledAuthenticator extends SpnegoAuthenticator {
|
||||
|
||||
@Override
|
||||
public void authenticate(AuthenticationFlowContext context) {
|
||||
throw new IllegalStateException("Not possible to authenticate as Kerberos feature is disabled");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -94,7 +94,7 @@ public class ProviderManager {
|
|||
List<ProviderFactory> f = loader.load(spi);
|
||||
if (f != null) {
|
||||
for (ProviderFactory pf: f) {
|
||||
String uniqueId = spi.getName() + "-" + pf.getId();
|
||||
String uniqueId = spi.getName() + "-" + pf.getId() + "-" + pf.getClass().getName();
|
||||
if (!loaded.contains(uniqueId)) {
|
||||
cache.add(spi.getProviderClass(), pf);
|
||||
loaded.add(uniqueId);
|
||||
|
|
|
@ -21,6 +21,7 @@ org.keycloak.authentication.authenticators.browser.UsernameFormFactory
|
|||
org.keycloak.authentication.authenticators.browser.PasswordFormFactory
|
||||
org.keycloak.authentication.authenticators.browser.OTPFormAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.browser.SpnegoAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.browser.SpnegoDisabledAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.browser.IdentityProviderAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.conditional.ConditionalRoleAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.conditional.ConditionalUserConfiguredAuthenticatorFactory
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.util;
|
||||
|
||||
import org.junit.Assume;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class KerberosUtils {
|
||||
|
||||
public static boolean isKerberosSupportExpected() {
|
||||
String kerberosSupported = System.getProperty("auth.server.kerberos.supported");
|
||||
// Supported by default. It is considered unsupported just if explicitly disabled
|
||||
return !"false".equals(kerberosSupported);
|
||||
}
|
||||
|
||||
public static void assumeKerberosSupportExpected() {
|
||||
Assume.assumeThat("Kerberos feature is not expected to be supported by auth server", isKerberosSupportExpected(), is(true));
|
||||
}
|
||||
}
|
|
@ -44,6 +44,8 @@ import javax.ws.rs.BadRequestException;
|
|||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
|
||||
import static org.keycloak.testsuite.util.KerberosUtils.assumeKerberosSupportExpected;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -84,6 +86,8 @@ public class UserStorageRestTest extends AbstractAdminTest {
|
|||
|
||||
@Test
|
||||
public void testKerberosAuthenticatorEnabledAutomatically() {
|
||||
assumeKerberosSupportExpected();
|
||||
|
||||
// Assert kerberos authenticator DISABLED
|
||||
AuthenticationExecutionInfoRepresentation kerberosExecution = findKerberosExecution();
|
||||
Assert.assertEquals(kerberosExecution.getRequirement(), AuthenticationExecutionModel.Requirement.DISABLED.toString());
|
||||
|
@ -141,6 +145,8 @@ public class UserStorageRestTest extends AbstractAdminTest {
|
|||
|
||||
@Test
|
||||
public void testKerberosAuthenticatorChangedOnlyIfDisabled() {
|
||||
assumeKerberosSupportExpected();
|
||||
|
||||
// Change kerberos to REQUIRED
|
||||
AuthenticationExecutionInfoRepresentation kerberosExecution = findKerberosExecution();
|
||||
kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString());
|
||||
|
@ -179,6 +185,8 @@ public class UserStorageRestTest extends AbstractAdminTest {
|
|||
// KEYCLOAK-4438
|
||||
@Test
|
||||
public void testKerberosAuthenticatorDisabledWhenProviderRemoved() {
|
||||
assumeKerberosSupportExpected();
|
||||
|
||||
// Assert kerberos authenticator DISABLED
|
||||
AuthenticationExecutionInfoRepresentation kerberosExecution = findKerberosExecution();
|
||||
Assert.assertEquals(kerberosExecution.getRequirement(), AuthenticationExecutionModel.Requirement.DISABLED.toString());
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentat
|
|||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
||||
import org.keycloak.testsuite.util.KerberosUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -119,6 +120,7 @@ public class InitialFlowsTest extends AbstractAuthenticationTest {
|
|||
|
||||
private LinkedList<FlowExecutions> expectedFlows() {
|
||||
LinkedList<FlowExecutions> expected = new LinkedList<>();
|
||||
String[] kerberosAuthExpectedChoices = KerberosUtils.isKerberosSupportExpected() ? new String[]{REQUIRED, ALTERNATIVE, DISABLED} : new String[]{DISABLED};
|
||||
|
||||
AuthenticationFlowRepresentation flow = newFlow("browser", "browser based authentication", "basic-flow", true, true);
|
||||
addExecExport(flow, null, false, "auth-cookie", false, null, ALTERNATIVE, 10);
|
||||
|
@ -128,7 +130,7 @@ public class InitialFlowsTest extends AbstractAuthenticationTest {
|
|||
|
||||
List<AuthenticationExecutionInfoRepresentation> execs = new LinkedList<>();
|
||||
addExecInfo(execs, "Cookie", "auth-cookie", false, 0, 0, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "Kerberos", "auth-spnego", false, 0, 1, DISABLED, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "Kerberos", "auth-spnego", false, 0, 1, DISABLED, null, kerberosAuthExpectedChoices);
|
||||
addExecInfo(execs, "Identity Provider Redirector", "identity-provider-redirector", true, 0, 2, ALTERNATIVE, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "forms", null, false, 0, 3, ALTERNATIVE, true, new String[]{REQUIRED, ALTERNATIVE, DISABLED, CONDITIONAL});
|
||||
addExecInfo(execs, "Username Password Form", "auth-username-password-form", false, 1, 0, REQUIRED, null, new String[]{REQUIRED});
|
||||
|
@ -199,7 +201,7 @@ public class InitialFlowsTest extends AbstractAuthenticationTest {
|
|||
addExecInfo(execs, "Authentication Options", null, false, 0, 1, REQUIRED, true, new String[]{REQUIRED, ALTERNATIVE, DISABLED, CONDITIONAL});
|
||||
addExecInfo(execs, "Basic Auth Challenge", "basic-auth", false, 1, 0, REQUIRED, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "Basic Auth Password+OTP", "basic-auth-otp", false, 1, 1, DISABLED, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "Kerberos", "auth-spnego", false, 1, 2, DISABLED, null, new String[]{REQUIRED, ALTERNATIVE, DISABLED});
|
||||
addExecInfo(execs, "Kerberos", "auth-spnego", false, 1, 2, DISABLED, null, kerberosAuthExpectedChoices);
|
||||
expected.add(new FlowExecutions(flow, execs));
|
||||
|
||||
flow = newFlow("registration", "registration flow", "basic-flow", true, true);
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.representations.idm.AuthenticatorConfigInfoRepresentation;
|
|||
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.ProfileAssume;
|
||||
import org.keycloak.testsuite.util.KerberosUtils;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -145,7 +146,10 @@ public class ProvidersTest extends AbstractAuthenticationTest {
|
|||
if (ProfileAssume.isFeatureEnabled(Profile.Feature.SCRIPTS)) {
|
||||
addProviderInfo(result, "auth-script-based", "Script", "Script based authentication. Allows to define custom authentication logic via JavaScript.");
|
||||
}
|
||||
addProviderInfo(result, "auth-spnego", "Kerberos", "Initiates the SPNEGO protocol. Most often used with Kerberos.");
|
||||
String kerberosHelpMessage = (KerberosUtils.isKerberosSupportExpected())
|
||||
? "Initiates the SPNEGO protocol. Most often used with Kerberos."
|
||||
: "DISABLED. Please enable Kerberos feature and make sure Kerberos available in your platform. Initiates the SPNEGO protocol. Most often used with Kerberos.";
|
||||
addProviderInfo(result, "auth-spnego", "Kerberos", kerberosHelpMessage);
|
||||
addProviderInfo(result, "auth-username-password-form", "Username Password Form",
|
||||
"Validates a username and password from login form.");
|
||||
addProviderInfo(result, "auth-x509-client-username-form", "X509/Validate Username Form",
|
||||
|
|
|
@ -71,6 +71,7 @@ import org.keycloak.testsuite.ProfileAssume;
|
|||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.util.KerberosRule;
|
||||
import org.keycloak.testsuite.util.KerberosUtils;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
|
@ -132,6 +133,11 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
|
|||
ProfileAssume.assumeFeatureDisabled(Feature.MAP_STORAGE);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void checkKerberosSupportedByAuthServer() {
|
||||
KerberosUtils.assumeKerberosSupportExpected();
|
||||
}
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void beforeAbstractKeycloakTest() throws Exception {
|
||||
|
|
|
@ -20,3 +20,4 @@ KcSamlFirstBrokerLoginTest
|
|||
KcSamlEncryptedIdTest
|
||||
KcSamlSignedBrokerTest
|
||||
KcSamlSpDescriptorTest
|
||||
KerberosLdapTest
|
||||
|
|
|
@ -266,6 +266,7 @@
|
|||
<auth.server.fips.mode>disabled</auth.server.fips.mode>
|
||||
<auth.server.supported.keystore.types>JKS,PKCS12,BCFKS</auth.server.supported.keystore.types>
|
||||
<auth.server.supported.rsa.key.sizes>1024,2048,4096</auth.server.supported.rsa.key.sizes>
|
||||
<auth.server.kerberos.supported>true</auth.server.kerberos.supported>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -692,6 +693,7 @@
|
|||
<auth.server.fips.keystore.type>${auth.server.fips.keystore.type}</auth.server.fips.keystore.type>
|
||||
<auth.server.supported.keystore.types>${auth.server.supported.keystore.types}</auth.server.supported.keystore.types>
|
||||
<auth.server.supported.rsa.key.sizes>${auth.server.supported.rsa.key.sizes}</auth.server.supported.rsa.key.sizes>
|
||||
<auth.server.kerberos.supported>${auth.server.kerberos.supported}</auth.server.kerberos.supported>
|
||||
|
||||
<!--
|
||||
~ Used for Wildfly Elytron 1.13.0.CR3+ RESTEasy client SSL truststore configuration.
|
||||
|
@ -1570,6 +1572,7 @@
|
|||
<auth.server.fips.mode>enabled</auth.server.fips.mode>
|
||||
|
||||
<auth.server.supported.keystore.types>PKCS12,BCFKS</auth.server.supported.keystore.types>
|
||||
<auth.server.kerberos.supported>false</auth.server.kerberos.supported>
|
||||
|
||||
<auth.server.keystore.type>pkcs12</auth.server.keystore.type>
|
||||
<auth.server.keystore>${auth.server.config.dir}/keycloak-fips.keystore.${auth.server.keystore.type}</auth.server.keystore>
|
||||
|
|
|
@ -312,7 +312,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<fieldset data-ng-show="serverInfo.featureEnabled('KERBEROS')">
|
||||
<legend id="kerberosIntegrationHeader" collapsed><span class="text">{{:: 'kerberos-integration' | translate}}</span></legend>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="allowKerberosAuthentication">{{:: 'allow-kerberos-authentication' | translate}} </label>
|
||||
|
|
Loading…
Reference in a new issue