diff --git a/dev/README.md b/dev/README.md
new file mode 100644
index 00000000000..a3ada172d70
--- /dev/null
+++ b/dev/README.md
@@ -0,0 +1,49 @@
+# Tools for development
+
+In this folder is some additional configuration that can be useful for local development. None of this should be deployed directly to production
+
+# Set up keycloak for cBioPortal >v6
+
+Requirements:
+- System runs docker (including docker compose)
+
+ 1. Run from the root of the repository:
+
+```
+cd dev
+docker compose up -d
+```
+
+2. (Option 1) Apply SAML2 configuration to _security.properties_ in cBioPortal:
+
+```properties
+authenticate=saml
+spring.security.saml2.relyingparty.registration.keycloak.assertingparty.metadata-uri=http://localhost:8084/realms/cbio/protocol/saml/descriptor
+spring.security.saml2.relyingparty.registration.keycloak.assertingparty.entity-id=http://localhost:8084/realms/cbio
+spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal
+spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].certificate-location=classpath:/dev/security/signing-cert.pem
+spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].private-key-location=classpath:/dev/security/signing-key.pem
+```
+
+3. (Option 2) Apply OIDC configuration to _security.properties_ in cBioPortal:
+
+```properties
+WIP
+```
+
+4. Set the following in _portal.properties_:
+
+```properties
+persistence.cache_type=no-cache
+session.service.url=http://localhost:5000/api/sessions/my_portal/
+
+spring.datasource.url=jdbc:mysql://localhost:3306/cbioportal?useSSL=false&allowPublicKeyRetrieval=true
+spring.datasource.username=cbio_user
+spring.datasource.password=somepassword
+spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+```
+
+4. Start cBioPortal application on port 8080. The login credentials are `testuser:P@assword1`.
+
+⚠️ Warning: Do not use this directly for production use as it takes several shortcuts to get a quick keycloak instance up.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3abc497a843..a9eef93e901 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
com.github.cbioportal
v5.4.9
-
+
2.13.1
diff --git a/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java b/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java
index 8d60df36224..ba5040df14d 100644
--- a/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java
+++ b/src/main/java/org/cbioportal/persistence/mybatis/StudyMyBatisRepository.java
@@ -8,6 +8,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
+import java.util.ArrayList;
import java.util.List;
@Repository
@@ -55,7 +56,9 @@ public CancerStudyTags getTags(String studyId) {
@Override
public List getTagsForMultipleStudies(List studyIds) {
-
+ if (studyIds == null || studyIds.isEmpty()) {
+ return new ArrayList<>();
+ }
return studyMapper.getTagsForMultipleStudies(studyIds);
}
}
diff --git a/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java b/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java
index eb6daaec565..3fdeabfb099 100644
--- a/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java
+++ b/src/main/java/org/cbioportal/security/config/Saml2SecurityConfig.java
@@ -1,12 +1,14 @@
package org.cbioportal.security.config;
import org.cbioportal.security.util.GrantedAuthorityUtil;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
@@ -14,8 +16,15 @@
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
+import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
+import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
+import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutRequestResolver;
+import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2RelyingPartyInitiatedLogoutSuccessHandler;
+import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.util.Collection;
@@ -23,28 +32,43 @@
import java.util.Objects;
import java.util.Set;
+@Configuration
@EnableWebSecurity
@ConditionalOnProperty(value = "authenticate", havingValue = "saml")
public class Saml2SecurityConfig {
+
+ @Autowired
+ private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
+
@Bean
public SecurityFilterChain samlFilterChain(HttpSecurity http) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
authenticationProvider.setResponseAuthenticationConverter(rolesConverter());
-
- return http.authorizeHttpRequests(auth ->
- auth.requestMatchers("/api/health", "/login", "/images/**").permitAll()
+ DefaultSecurityFilterChain build = http
+ // FIXME - csrf should be enabled
+ .csrf(AbstractHttpConfigurer::disable)
+ .authorizeHttpRequests(auth ->
+ auth.requestMatchers("/api/health", "/images/**", "/js/**").permitAll()
.anyRequest().authenticated())
- .exceptionHandling(eh ->
- eh.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**")))
+ .exceptionHandling(eh ->
+ eh.defaultAuthenticationEntryPointFor(
+ new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AntPathRequestMatcher.antMatcher("/api/**")
+ )
+ )
.saml2Login(saml2 -> saml2
.authenticationManager(new ProviderManager(authenticationProvider))
)
- .logout(logout -> logout.logoutSuccessUrl("/login?logout_success"))
- // FIXME - csrf should be enabled
- .csrf(AbstractHttpConfigurer::disable)
+ // NOTE: I did not get the official .saml2Logout() DSL to work as
+ // described at https://docs.spring.io/spring-security/reference/6.1/servlet/saml2/logout.html
+ // Logout Service POST Binding URL: http://localhost:8080/logout/saml2/slo
+ .logout(logout -> logout
+ .logoutUrl("/saml/logout")
+ .logoutSuccessHandler(logoutSuccessHandler())
+ )
.build();
+ return build;
}
-
+
private Converter rolesConverter() {
Converter delegate =
@@ -63,4 +87,15 @@ private Converter getTags(
}
@PreAuthorize("hasPermission(#studyIds, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)")
+ @PreFilter("hasPermission(#studyIds, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)")
@RequestMapping(value = "/studies/tags/fetch", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(description = "Get the study tags by IDs")
diff --git a/src/main/resources/dev/security/keycloak-configuration-generated.json b/src/main/resources/dev/security/keycloak-configuration-generated.json
new file mode 100644
index 00000000000..1e8e9329f76
--- /dev/null
+++ b/src/main/resources/dev/security/keycloak-configuration-generated.json
@@ -0,0 +1,1913 @@
+{
+ "id": "cbio",
+ "realm": "cbio",
+ "displayName": "cBioPortal",
+ "notBefore": 0,
+ "defaultSignatureAlgorithm": "RS256",
+ "revokeRefreshToken": false,
+ "refreshTokenMaxReuse": 0,
+ "accessTokenLifespan": 300,
+ "accessTokenLifespanForImplicitFlow": 900,
+ "ssoSessionIdleTimeout": 1800,
+ "ssoSessionMaxLifespan": 36000,
+ "ssoSessionIdleTimeoutRememberMe": 0,
+ "ssoSessionMaxLifespanRememberMe": 0,
+ "offlineSessionIdleTimeout": 2592000,
+ "offlineSessionMaxLifespanEnabled": false,
+ "offlineSessionMaxLifespan": 5184000,
+ "clientSessionIdleTimeout": 0,
+ "clientSessionMaxLifespan": 0,
+ "clientOfflineSessionIdleTimeout": 0,
+ "clientOfflineSessionMaxLifespan": 0,
+ "accessCodeLifespan": 60,
+ "accessCodeLifespanUserAction": 300,
+ "accessCodeLifespanLogin": 1800,
+ "actionTokenGeneratedByAdminLifespan": 43200,
+ "actionTokenGeneratedByUserLifespan": 300,
+ "oauth2DeviceCodeLifespan": 600,
+ "oauth2DevicePollingInterval": 5,
+ "enabled": true,
+ "sslRequired": "none",
+ "registrationAllowed": false,
+ "registrationEmailAsUsername": false,
+ "rememberMe": false,
+ "verifyEmail": false,
+ "loginWithEmailAllowed": false,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "editUsernameAllowed": false,
+ "bruteForceProtected": false,
+ "permanentLockout": false,
+ "maxFailureWaitSeconds": 900,
+ "minimumQuickLoginWaitSeconds": 60,
+ "waitIncrementSeconds": 60,
+ "quickLoginCheckMilliSeconds": 1000,
+ "maxDeltaTimeSeconds": 43200,
+ "failureFactor": 30,
+ "defaultRole": {
+ "id": "bb770785-c99d-4491-ac1c-6f1a571e43dc",
+ "name": "default-roles-cbio",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "clientRole": false,
+ "containerId": "cbio"
+ },
+ "defaultGroups": [
+ "/PUBLIC_STUDIES"
+ ],
+ "requiredCredentials": [
+ "password"
+ ],
+ "otpPolicyType": "totp",
+ "otpPolicyAlgorithm": "HmacSHA1",
+ "otpPolicyInitialCounter": 0,
+ "otpPolicyDigits": 6,
+ "otpPolicyLookAheadWindow": 1,
+ "otpPolicyPeriod": 30,
+ "otpSupportedApplications": [
+ "FreeOTP",
+ "Google Authenticator"
+ ],
+ "webAuthnPolicyRpEntityName": "keycloak",
+ "webAuthnPolicySignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyRpId": "",
+ "webAuthnPolicyAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyRequireResidentKey": "not specified",
+ "webAuthnPolicyUserVerificationRequirement": "not specified",
+ "webAuthnPolicyCreateTimeout": 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyAcceptableAaguids": [],
+ "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyPasswordlessRpId": "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout": 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+ "scopeMappings": [
+ {
+ "clientScope": "offline_access",
+ "roles": [
+ "offline_access"
+ ]
+ }
+ ],
+ "clientScopeMappings": {
+ "account": [
+ {
+ "client": "account-console",
+ "roles": [
+ "manage-account"
+ ]
+ }
+ ]
+ },
+ "clients": [
+ {
+ "id": "447cb732-9d28-411b-b712-22a7986c029e",
+ "clientId": "account",
+ "name": "${client_account}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/cbio/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/cbio/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "fc7e8395-b7f3-43d3-9c07-3c7e3cacb7ee",
+ "clientId": "account-console",
+ "name": "${client_account-console}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/cbio/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/cbio/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "3cf582e8-7b31-448d-972b-32ce17e9527b",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "91156b1e-4585-440c-a706-058af196d622",
+ "clientId": "admin-cli",
+ "name": "${client_admin-cli}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": false,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "83f338ca-c017-428e-818b-f497a4d0a493",
+ "clientId": "broker",
+ "name": "${client_broker}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "4b5c2aa6-bc44-458d-ac1f-1a2166520f4d",
+ "clientId": "cbioportal",
+ "adminUrl": "http://localhost:8084/saml",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "http://localhost:8080/*"
+ ],
+ "webOrigins": [
+ "http://localhost:8080"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "saml",
+ "attributes": {
+ "saml.assertion.signature": "false",
+ "saml.force.post.binding": "false",
+ "saml_single_logout_service_url_post": "http://localhost:8080/logout/saml2/slo",
+ "signing.private.key": "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",
+ "saml.server.signature": "true",
+ "saml.signing.certificate": "MIIFazCCA1OgAwIBAgIUVMt2XXqYekaunKy/fhcJNQzJ0uQwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMTkxMzUyMzFaFw0yMjExMTkxMzUyMzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0HY/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkWFIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVuHQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe319FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3Puyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4tGwIDAQABo1MwUTAdBgNVHQ4EFgQU0JL52xvzhG/48H01Rxac3MOgZYEwHwYDVR0jBBgwFoAU0JL52xvzhG/48H01Rxac3MOgZYEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAYYbj4v37eUTo9mtWgtZ2hHjWtdScPlZGxZanPZZpAcN8JR07ps/wow68rQMOZR9hFS6c2+izbn3HkR3OwCK9sZeuWzrLVPUBSiXxEbRkpK/pXAd/Irat+f1ylA3j3J4VyDJymqiuIBOE9kzGWpbMdyqlHdH5XG/giLEOY66p6k5QrtKDXKzfQ7BBzO1WTe1BkWp7HerEKqM7mRSA4pRT5J7UAGn4gHOU39bnOHZPhko/rFagI2iO8T3fSBL+IWx76ROoG3DUnaZmDIuMxzeEZD7G8aPWOJCP0/mnBrAQhsEUg0bcsRa6qzWFigY4oWjxOSc2aQMRSjxrVf59Geplyhh8AY0yI49uhJJc6SztwuiX9fksCm1/Z9YZeeJr/oOkBduGpX6BQbPA7N2yKg5APdn8DVIHFALijwobz+94+d6uv4+ihlQ8jBgbo1kwMZps+BAVOODgX3RpFKmqcyX9bjWaapw+XE1U8Rtt3mcgN9qchvcIqcnGZ1PfaY1ultvAzUa4TCECiYRXSOXT4iAXv+M1i2XisuThtw7dC9HMY1D/0oA/cRxwknLsuKRRGJWbUN/Ts4GMjLmvKejQOWfS+/wHS9kQdPKS3BKZYQgqli4OG1xRErykL6SRWTKJA3+VNditbHFkJuL9dGZLu0Dmaww6K1SSnYai77uTTPdOHoc=",
+ "saml.artifact.binding.identifier": "eY7tz0hmV0aMmBtL/oU7BOy5kUY=",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml_force_name_id_format": "true",
+ "saml.client.signature": "false",
+ "saml.authnstatement": "true",
+ "saml_name_id_format": "email",
+ "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": -1,
+ "protocolMappers": [
+ {
+ "id": "fab43918-1994-40d4-8b4c-d0e41de7d61b",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ },
+ {
+ "id": "ef7aa6fb-3bbe-478b-808e-6d56d5c8c87c",
+ "name": "X500 email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "attribute.nameformat": "Basic",
+ "user.attribute": "email",
+ "friendly.name": "email",
+ "attribute.name": "email"
+ }
+ }
+ ],
+ "defaultClientScopes": [],
+ "optionalClientScopes": []
+ },
+ {
+ "id": "f6045634-733c-43e6-9ec5-baabd518db6c",
+ "clientId": "cbioportal_oauth2",
+ "name": "cBioPortal OIDC client",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "client_secret",
+ "redirectUris": [
+ "http://localhost:8080/*"
+ ],
+ "webOrigins": [
+ "http://localhost:8080"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "protocolMappers": [
+ {
+ "id": "08812f2b-f12f-4460-93d0-ca9d5fadf4b8",
+ "name": "cbioportal_api_audience",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-mapper",
+ "consentRequired": false,
+ "config": {
+ "included.client.audience": "cbioportal_api",
+ "id.token.claim": "false",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "false"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "email"
+ ],
+ "optionalClientScopes": [
+ "offline_access",
+ "roles"
+ ]
+ },
+ {
+ "id": "8d317944-4523-43e9-a198-431be79edb0f",
+ "clientId": "realm-management",
+ "name": "${client_realm-management}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "0f4c7e47-9f6b-4171-8290-283f62d02701",
+ "clientId": "security-admin-console",
+ "name": "${client_security-admin-console}",
+ "rootUrl": "${authAdminUrl}",
+ "baseUrl": "/admin/cbio/console/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/admin/cbio/console/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "831f7ad1-c369-4237-942f-88626cec64e3",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ }
+ ],
+ "clientScopes": [
+ {
+ "id": "6624568b-9db3-46ab-9d95-8419753ad28c",
+ "name": "role_list",
+ "description": "SAML role list",
+ "protocol": "saml",
+ "attributes": {
+ "consent.screen.text": "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "564b568d-911b-442a-a490-a423d974caef",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ }
+ ]
+ },
+ {
+ "id": "2c2c551a-e90f-4adc-b09a-12421ecfc1f2",
+ "name": "microprofile-jwt",
+ "description": "Microprofile - JWT built-in scope",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "d9dbf260-7b93-4044-ba15-68bc45facc72",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "multivalued": "true",
+ "user.attribute": "foo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "f4a0ae6d-2f2d-48d4-a55e-d9860b2e348d",
+ "name": "upn",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "upn",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "efd3125c-7be3-4550-9862-3ec9039102e8",
+ "name": "offline_access",
+ "description": "OpenID Connect built-in scope: offline_access",
+ "protocol": "openid-connect",
+ "attributes": {
+ "consent.screen.text": "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen": "true"
+ }
+ },
+ {
+ "id": "2cbfef6c-ea0d-4fc0-a386-17986ce68c8f",
+ "name": "web-origins",
+ "description": "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false",
+ "consent.screen.text": ""
+ },
+ "protocolMappers": [
+ {
+ "id": "c362e4af-0bca-4cda-8ce8-08fbe6ed93b7",
+ "name": "allowed web origins",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-allowed-origins-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ]
+ },
+ {
+ "id": "261ac9c1-0f3e-43fb-b85c-6ef615631051",
+ "name": "phone",
+ "description": "OpenID Connect built-in scope: phone",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${phoneScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "03c75c00-2b46-4cfc-85b0-37813f4730c8",
+ "name": "phone number",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumber",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "5b81ae41-fb64-4e5e-9165-ecd74d27160c",
+ "name": "phone number verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumberVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "38806f4c-bff9-41c6-b111-36dd67953b13",
+ "name": "roles",
+ "description": "OpenID Connect scope for add user roles to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${rolesScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "39bdb32a-43e9-4193-ab6d-73315dd1edb2",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ },
+ {
+ "id": "4e09ee37-8e25-4335-a98b-c88945ab00b4",
+ "name": "realm roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "realm_access.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ },
+ {
+ "id": "dbcdd3b9-3fbb-46bb-b0eb-e924d7982c1a",
+ "name": "client roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-client-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "multivalued": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "resource_access.${client_id}.roles",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "ba043066-3611-44f3-8ce7-0d63ee7214e6",
+ "name": "email",
+ "description": "OpenID Connect built-in scope: email",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${emailScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "3a55b7fa-84bd-4f68-9ed2-34359b04c3c2",
+ "name": "email",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "email",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "09fc3174-1c39-4a98-8727-8571d7196213",
+ "name": "email verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "emailVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "39463f1e-621e-411a-8820-a9b83d579fc5",
+ "name": "profile",
+ "description": "OpenID Connect built-in scope: profile",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${profileScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "c65a4612-d8e1-4588-886b-8e7946acf5a9",
+ "name": "full name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-full-name-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ },
+ {
+ "id": "78ec825f-a961-490e-8128-659d1d70c4e6",
+ "name": "birthdate",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "birthdate",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "birthdate",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "65cae517-5bf6-4af0-90da-7ed6cff2a6a3",
+ "name": "username",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "preferred_username",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "4bd831ec-e2db-45b8-8d20-c2636d9b592e",
+ "name": "profile",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "profile",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "profile",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "8275c531-59cd-450a-9499-53549aedda41",
+ "name": "gender",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "gender",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "gender",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "aa3a327a-7039-4f67-94ae-972d5be7b1af",
+ "name": "zoneinfo",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "zoneinfo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "zoneinfo",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "97591cbb-a403-49b2-8f34-192913218437",
+ "name": "website",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "website",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "website",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "bedf23ca-a1fd-40a5-8acb-19bedf7da354",
+ "name": "picture",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "picture",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "picture",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "40988b4c-3c7f-415c-9bf5-f4463b611fc2",
+ "name": "family name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "lastName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "family_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "d3f3f74d-c9ab-4d0a-8ebd-51673cdbf151",
+ "name": "updated at",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "updatedAt",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "updated_at",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "1973c75f-bc92-48a4-ac74-fb900dabe17a",
+ "name": "given name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "firstName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "given_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "321e898f-d85c-4d8e-9900-1cf94b49fff1",
+ "name": "middle name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "middleName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "middle_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "bb4b6b50-8cc9-45b3-be23-6a2671f0bcf0",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "ddaf0658-e10d-4a8a-8657-16c69eaa7d1e",
+ "name": "nickname",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "nickname",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "nickname",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "17e90911-d87b-44de-9448-8e8ed92c5ae7",
+ "name": "address",
+ "description": "OpenID Connect built-in scope: address",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${addressScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "a0e1d5be-5d5f-49b1-8467-9052561914e9",
+ "name": "address",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-address-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute.formatted": "formatted",
+ "user.attribute.country": "country",
+ "user.attribute.postal_code": "postal_code",
+ "userinfo.token.claim": "true",
+ "user.attribute.street": "street",
+ "id.token.claim": "true",
+ "user.attribute.region": "region",
+ "access.token.claim": "true",
+ "user.attribute.locality": "locality"
+ }
+ }
+ ]
+ }
+ ],
+ "defaultDefaultClientScopes": [
+ "web-origins",
+ "roles",
+ "profile",
+ "role_list",
+ "email"
+ ],
+ "defaultOptionalClientScopes": [
+ "address",
+ "phone",
+ "microprofile-jwt",
+ "offline_access"
+ ],
+ "browserSecurityHeaders": {
+ "contentSecurityPolicyReportOnly": "",
+ "xContentTypeOptions": "nosniff",
+ "xRobotsTag": "none",
+ "xFrameOptions": "SAMEORIGIN",
+ "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection": "1; mode=block",
+ "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer": {},
+ "eventsEnabled": false,
+ "eventsListeners": [
+ "jboss-logging"
+ ],
+ "enabledEventTypes": [],
+ "adminEventsEnabled": false,
+ "adminEventsDetailsEnabled": false,
+ "identityProviders": [],
+ "identityProviderMappers": [],
+ "components": {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+ {
+ "id": "889a17cb-5649-4149-8582-33076c1c3317",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "4c79fd7c-b4fe-470d-8786-f58ab99a518e",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "6fbe15a3-e5b2-4342-97cb-bde10366963c",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "saml-user-attribute-mapper",
+ "oidc-full-name-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "saml-user-property-mapper",
+ "oidc-address-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "oidc-usermodel-property-mapper",
+ "saml-role-list-mapper"
+ ]
+ }
+ },
+ {
+ "id": "c7824d6e-b0e6-49cc-bff6-68b2f011a542",
+ "name": "Trusted Hosts",
+ "providerId": "trusted-hosts",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "host-sending-registration-request-must-match": [
+ "true"
+ ],
+ "client-uris-must-match": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "196f1f2a-bc8b-425a-89d9-86cdfb20fcfd",
+ "name": "Max Clients Limit",
+ "providerId": "max-clients",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "max-clients": [
+ "200"
+ ]
+ }
+ },
+ {
+ "id": "9e90ed2b-a6a2-42fd-988e-58ea0ddeb63d",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "oidc-full-name-mapper",
+ "saml-role-list-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-user-property-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "oidc-address-mapper",
+ "oidc-usermodel-property-mapper"
+ ]
+ }
+ },
+ {
+ "id": "2ce4cd15-6601-482f-81e2-c7c5621e06f9",
+ "name": "Full Scope Disabled",
+ "providerId": "scope",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "1375acc0-7aa9-4b3f-a0c0-a40c290e3f73",
+ "name": "Consent Required",
+ "providerId": "consent-required",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ }
+ ],
+ "org.keycloak.keys.KeyProvider": [
+ {
+ "id": "53680454-4c6c-4486-861f-e5e74befe868",
+ "name": "hmac-generated",
+ "providerId": "hmac-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "HS256"
+ ]
+ }
+ },
+ {
+ "id": "e684156b-42ad-4576-b047-e1cb35f3fc05",
+ "name": "rsa-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "keyUse": [
+ "sig"
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "014ff5f5-de31-48d2-952f-1445e8da62e1",
+ "name": "aes-generated",
+ "providerId": "aes-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "557a3a1f-1036-4fd5-8656-35ef6c482f50",
+ "name": "rsa-enc-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "keyUse": [
+ "enc"
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ }
+ ]
+ },
+ "internationalizationEnabled": false,
+ "supportedLocales": [],
+ "authenticationFlows": [
+ {
+ "id": "d09f86a8-3eb7-4b08-8c02-36a56f6a2a2c",
+ "alias": "Account verification options",
+ "description": "Method with which to verity the existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-email-verification",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "flowAlias": "Verify Existing Account by Re-authentication",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "3801ca86-b775-4af6-a7cc-a5125e1a67b1",
+ "alias": "Authentication Options",
+ "description": "Authentication options.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "basic-auth",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "basic-auth-otp",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "2f229147-9906-45ed-bbf9-a7cb9e0a6650",
+ "alias": "Browser - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "50e71410-d2fd-4b68-8972-c9e49ecee7c0",
+ "alias": "Direct Grant - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "direct-grant-validate-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "7f4cfad2-bd68-4ac4-8d8d-d22ed18214fe",
+ "alias": "First broker login - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "dbbb7d22-5602-4ce4-aa53-40bf6391b50c",
+ "alias": "Handle Existing Account",
+ "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-confirm-link",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "Account verification options",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "6e414865-f4f0-4295-83f4-ca5edce533f0",
+ "alias": "Reset - Conditional OTP",
+ "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "85f5eeb7-78e7-4ef4-962e-c23fba388dd6",
+ "alias": "User creation or linking",
+ "description": "Flow for the existing/non-existing user alternatives",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "create unique user config",
+ "authenticator": "idp-create-user-if-unique",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "flowAlias": "Handle Existing Account",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "4e9649e7-a343-4f82-8293-c020c26e14d5",
+ "alias": "Verify Existing Account by Re-authentication",
+ "description": "Reauthentication of existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "flowAlias": "First broker login - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "c4297697-2daf-4b81-9340-2244f5f6f4d1",
+ "alias": "browser",
+ "description": "browser based authentication",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-cookie",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "identity-provider-redirector",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 25,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "flowAlias": "forms",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "c9f07e45-6e38-45e8-938d-7314d2596b63",
+ "alias": "clients",
+ "description": "Base authentication for clients",
+ "providerId": "client-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "client-secret",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-secret-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-x509",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 40,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "55cf854b-47fb-4b05-9eef-6840f92fee79",
+ "alias": "direct grant",
+ "description": "OpenID Connect Resource Owner Grant",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "direct-grant-validate-username",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "direct-grant-validate-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 30,
+ "flowAlias": "Direct Grant - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "14fe6c33-9d93-4c95-988b-d5e0a1d2fe4b",
+ "alias": "docker auth",
+ "description": "Used by Docker clients to authenticate against the IDP",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "docker-http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "bce646e3-ebd1-4d8e-8703-ea91621f3550",
+ "alias": "first broker login",
+ "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "review profile config",
+ "authenticator": "idp-review-profile",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "User creation or linking",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "fae27840-4d5e-4a27-a1b5-1b44414b776f",
+ "alias": "forms",
+ "description": "Username, password, otp and other auth forms.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "flowAlias": "Browser - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "d391fa3e-0975-4db4-8ab1-d2f8348ed395",
+ "alias": "http challenge",
+ "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "no-cookie-redirect",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "Authentication Options",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "380a97f7-a283-4716-88e9-c21e5efd3867",
+ "alias": "registration",
+ "description": "registration flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-page-form",
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "flowAlias": "registration form",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "0a5ea500-02e9-490a-9cb4-b7d030ed3372",
+ "alias": "registration form",
+ "description": "registration form",
+ "providerId": "form-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-user-creation",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-profile-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 40,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-password-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 50,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-recaptcha-action",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 60,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "1dace197-f541-4109-9c50-aa172ce6ac14",
+ "alias": "reset credentials",
+ "description": "Reset credentials for a user if they forgot their password or something",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "reset-credentials-choose-user",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-credential-email",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 40,
+ "flowAlias": "Reset - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "744c784a-2933-4ea7-9c98-b89b37cdfafc",
+ "alias": "saml ecp",
+ "description": "SAML ECP Profile Authentication Flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ }
+ ],
+ "authenticatorConfig": [
+ {
+ "id": "0231eced-f393-479f-9d3e-0deb23879cd2",
+ "alias": "create unique user config",
+ "config": {
+ "require.password.update.after.registration": "false"
+ }
+ },
+ {
+ "id": "24782868-8536-44aa-a808-c8af37085ce5",
+ "alias": "review profile config",
+ "config": {
+ "update.profile.on.first.login": "missing"
+ }
+ }
+ ],
+ "requiredActions": [
+ {
+ "alias": "CONFIGURE_TOTP",
+ "name": "Configure OTP",
+ "providerId": "CONFIGURE_TOTP",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 10,
+ "config": {}
+ },
+ {
+ "alias": "terms_and_conditions",
+ "name": "Terms and Conditions",
+ "providerId": "terms_and_conditions",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 20,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PASSWORD",
+ "name": "Update Password",
+ "providerId": "UPDATE_PASSWORD",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 30,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PROFILE",
+ "name": "Update Profile",
+ "providerId": "UPDATE_PROFILE",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 40,
+ "config": {}
+ },
+ {
+ "alias": "VERIFY_EMAIL",
+ "name": "Verify Email",
+ "providerId": "VERIFY_EMAIL",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 50,
+ "config": {}
+ },
+ {
+ "alias": "delete_account",
+ "name": "Delete Account",
+ "providerId": "delete_account",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 60,
+ "config": {}
+ },
+ {
+ "alias": "update_user_locale",
+ "name": "Update User Locale",
+ "providerId": "update_user_locale",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 1000,
+ "config": {}
+ }
+ ],
+ "browserFlow": "browser",
+ "registrationFlow": "registration",
+ "directGrantFlow": "direct grant",
+ "resetCredentialsFlow": "reset credentials",
+ "clientAuthenticationFlow": "clients",
+ "dockerAuthenticationFlow": "docker auth",
+ "attributes": {
+ "cibaBackchannelTokenDeliveryMode": "poll",
+ "cibaExpiresIn": "120",
+ "cibaAuthRequestedUserHint": "login_hint",
+ "oauth2DeviceCodeLifespan": "600",
+ "oauth2DevicePollingInterval": "5",
+ "parRequestUriLifespan": "60",
+ "cibaInterval": "5"
+ },
+ "keycloakVersion": "15.0.2",
+ "userManagedAccessAllowed": false,
+ "clientProfiles": {
+ "profiles": []
+ },
+ "clientPolicies": {
+ "policies": []
+ },
+ "users": [
+ {
+ "username": "testuser",
+ "enabled": true,
+ "email": "testuser@thehyve.nl",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "P@ssword1"
+ }
+ ],
+ "realmRoles": [
+ "offline_access"
+ ],
+ "groups": [
+ "/PUBLIC_STUDIES"
+ ]
+ }
+ ],
+ "roles": {
+ "client": {
+ "cbioportal": [
+ {
+ "name": "study_tcga_pub"
+ }
+ ]
+ }
+ },
+ "groups": [
+ {
+ "name": "PUBLIC_STUDIES",
+ "clientRoles": {
+ "cbioportal": [
+ "study_tcga_pub"
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/dev/security/signing-cert.pem b/src/main/resources/dev/security/signing-cert.pem
new file mode 100644
index 00000000000..01883dcafef
--- /dev/null
+++ b/src/main/resources/dev/security/signing-cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIUVMt2XXqYekaunKy/fhcJNQzJ0uQwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMTkxMzUyMzFaFw0yMjEx
+MTkxMzUyMzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDJTDNHzHv19kM4tVLOIjpR/vez4QJk70PMbghQBdCp
+1Er1yU8GkQRMx0QtumQB2ML1p2f63EEd7WsAPMEVYNQv6MHJDhAIDt+npWmYrGl3
+PrkVA3GNzZcD+GQEMZdGcECvfocOy2tB6iMOhdnFqu4L/QfFG2yJ+CpimpijvW78
+cJ35oYmOTnD7R9LBAJQuBlQDpOvB+I/dFeCiNKw61HQy0nMf6oe0pBy4E7bImQ0H
+Y/soxBnzbvPUzbBvnhb2d97l3wn6ElUMrZuQSyI+OyVgBMyv9gcgV4Wq16oEuNkW
+FIdY2j8GeiDlqy9KJAttgLXBjGua2lRML0a+nrfF1VbBLgyzAZZP2IS/P3QYcSE2
+GbPWiWXjov2vF63/VnARzQhPhuLGilWp1Nxqr0HztgSiAyx0D3wqEBic0ERAQDVu
+HQZdjPd7RJaJ6MBnZH9mMVQOrjspIP5Sc6Z7omou26LPTjWNwmNWnfrq1sU8ADg4
+Uj09PWYcuWhPKxe6K9Zm4PLGXA0fR/fCVPDKaJPXIC7FGzDDdh/uSb9OURlgHwe3
+19FCdvm1k7xD6tEfsyORjWJFoYvyT015j9LdBuO5fwt40EPCzNezqWCaimES7u3P
+uyg+4mbnRDh1UuouHOHVZ4jWySrrEktI0l6JkxrqdT2ilw7ICtmFx2fsjO9qso4t
+GwIDAQABo1MwUTAdBgNVHQ4EFgQU0JL52xvzhG/48H01Rxac3MOgZYEwHwYDVR0j
+BBgwFoAU0JL52xvzhG/48H01Rxac3MOgZYEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAgEAYYbj4v37eUTo9mtWgtZ2hHjWtdScPlZGxZanPZZpAcN8
+JR07ps/wow68rQMOZR9hFS6c2+izbn3HkR3OwCK9sZeuWzrLVPUBSiXxEbRkpK/p
+XAd/Irat+f1ylA3j3J4VyDJymqiuIBOE9kzGWpbMdyqlHdH5XG/giLEOY66p6k5Q
+rtKDXKzfQ7BBzO1WTe1BkWp7HerEKqM7mRSA4pRT5J7UAGn4gHOU39bnOHZPhko/
+rFagI2iO8T3fSBL+IWx76ROoG3DUnaZmDIuMxzeEZD7G8aPWOJCP0/mnBrAQhsEU
+g0bcsRa6qzWFigY4oWjxOSc2aQMRSjxrVf59Geplyhh8AY0yI49uhJJc6SztwuiX
+9fksCm1/Z9YZeeJr/oOkBduGpX6BQbPA7N2yKg5APdn8DVIHFALijwobz+94+d6u
+v4+ihlQ8jBgbo1kwMZps+BAVOODgX3RpFKmqcyX9bjWaapw+XE1U8Rtt3mcgN9qc
+hvcIqcnGZ1PfaY1ultvAzUa4TCECiYRXSOXT4iAXv+M1i2XisuThtw7dC9HMY1D/
+0oA/cRxwknLsuKRRGJWbUN/Ts4GMjLmvKejQOWfS+/wHS9kQdPKS3BKZYQgqli4O
+G1xRErykL6SRWTKJA3+VNditbHFkJuL9dGZLu0Dmaww6K1SSnYai77uTTPdOHoc=
+-----END CERTIFICATE-----
diff --git a/src/main/resources/dev/security/signing-key.pem b/src/main/resources/dev/security/signing-key.pem
new file mode 100644
index 00000000000..ee46d3f2156
--- /dev/null
+++ b/src/main/resources/dev/security/signing-key.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+KNSWUanv0GBYB9lnaY3wS/ncYpn8MQ==
+-----END PRIVATE KEY-----
diff --git a/src/main/resources/security.properties.EXAMPLE b/src/main/resources/security.properties.EXAMPLE
index fdedb60d6bb..994bbb3747b 100644
--- a/src/main/resources/security.properties.EXAMPLE
+++ b/src/main/resources/security.properties.EXAMPLE
@@ -43,13 +43,16 @@ authenticate=false
# TODO add to docs: metadata-uri can be both URL or metadata xml file
# Providing the SAML2 IDP metadata is sufficient to autoconfigure the provider. The 'metadata-uri' property can point to
# and HTTP endpoint or a metadata xml file on the file system.
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.assertingparty.metadata-uri=classpath:/client-tailored-saml-idp-metadata.xml
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.assertingparty.metadata-uri=http://localhost:8080/realms/cbioportal/protocol/saml/descriptor
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.entity-id=cbioportal-saml
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.signing.credentials[0].certificate-location=classpath:/local.crt
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.signing.credentials[0].private-key-location=classpath:/local.key
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.singlelogout.binding=POST
-#spring.security.saml2.relyingparty.registration.cbio-saml-idp.singlelogout.response-url=http://localhost:8080/logout/saml2/slo
+# Option 1 (when using a metadata xml file on the file system):
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.assertingparty.metadata-uri=classpath:/client-tailored-saml-idp-metadata.xml
+# Option 2 (when using an HTTP endpoint):
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.assertingparty.metadata-uri=http://localhost:8080/realms/cbioportal/protocol/saml/descriptor
+#spring.security.saml2.relyingparty.registration.keycloak.assertingparty.entity-id=https://mykeycloak.org/realms/cbio",
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.entity-id=cbioportal-saml
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.signing.credentials[0].certificate-location=classpath:/local.crt
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.signing.credentials[0].private-key-location=classpath:/local.key
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.singlelogout.binding=POST
+#spring.security.saml2.relyingparty.registration.cbio-saml-idp-id.singlelogout.response-url=http://mycbioportal.org/logout/saml2/slo
# TODO add to docs (in minutes; default 1)
spring.security.oauth2.allowed-clock-skew=
diff --git a/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java b/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java
index fd6ec885301..29d0c2ef940 100644
--- a/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java
+++ b/src/test/java/org/cbioportal/test/integration/security/SamlAuthIntegrationTest.java
@@ -3,17 +3,17 @@
import dasniko.testcontainers.keycloak.KeycloakContainer;
import org.cbioportal.PortalApplication;
import org.cbioportal.test.integration.*;
-import org.cbioportal.web.SessionServiceController;
import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
@@ -31,6 +31,7 @@
import java.io.IOException;
import java.time.Duration;
import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
import static org.cbioportal.test.integration.security.SamlAuthIntegrationTest.*;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@@ -52,7 +53,6 @@
"spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect",
// SAML settings
"spring.security.saml2.relyingparty.registration.keycloak.entity-id=cbioportal",
-// "spring.security.saml2.relyingparty.keycloak.allow-resp-null-signing=true",
"spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].certificate-location=classpath:security/signing-cert.pem",
"spring.security.saml2.relyingparty.registration.keycloak.signing.credentials[0].private-key-location=classpath:security/signing-key.pem",
"saml.idp.metadata.attribute.email=email",
@@ -71,6 +71,7 @@
MySamlKeycloakInitializer.class,
PortInitializer.class
})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SamlAuthIntegrationTest {
private final static int CBIO_PORT = 8080;
@@ -93,9 +94,6 @@ public class SamlAuthIntegrationTest {
@ClassRule
public static GenericContainer sessionService = SharedSessionServiceContainer.getInstance();
- @SpyBean
- private SessionServiceController sessionServiceController;
-
// Update application properties with connection info on Keycloak container
public static class MySamlKeycloakInitializer extends SamlKeycloakInitializer {
@Override
@@ -129,7 +127,8 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
}
@Test
- public void loginSuccess() {
+ public void a_loginSuccess() {
+ String vncAddress = chrome.getVncAddress();
RemoteWebDriver driver = performLogin();
WebElement loggedInButton = driver.findElement(By.id("dat-dropdown"));
Assertions.assertEquals("Logged in as testuser@thehyve.nl", loggedInButton.getText());
@@ -139,7 +138,7 @@ public void loginSuccess() {
}
@Test
- public void downloadOfflineToken() throws Exception {
+ public void b_downloadOfflineToken() throws Exception {
RemoteWebDriver driver = performLogin();
Assertions.assertDoesNotThrow(
() -> driver.findElement(By.id("dat-dropdown")).click(),
@@ -153,7 +152,7 @@ public void downloadOfflineToken() throws Exception {
}
@Test
- public void logoutSuccess() {
+ public void c_logoutSuccess() {
RemoteWebDriver driver = performLogin();
Assertions.assertDoesNotThrow(
() -> driver.findElement(By.id("dat-dropdown")).click(),
@@ -164,7 +163,26 @@ public void logoutSuccess() {
"IDP login screen not visible on the page. Logout did not work correctly."
);
}
-
+
+ @Test
+ public void d_loginAgainSuccess() {
+ final RemoteWebDriver driver = performLogin();
+ Assertions.assertDoesNotThrow(
+ () -> driver.findElement(By.id("dat-dropdown")).click(),
+ "Logout menu could not be found on the page.");
+ driver.findElement(By.linkText("Sign out")).click();
+ driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
+ Assertions.assertDoesNotThrow(
+ () -> driver.findElement(By.id("username")),
+ "IDP login screen not visible on the page. Logout did not work correctly."
+ );
+ final RemoteWebDriver newDriver = performLogin();
+ Assertions.assertDoesNotThrow(
+ () -> newDriver.findElement(By.id("dat-dropdown")),
+ "Logged-in menu could not be found on the page. Login did not work correctly.");
+ }
+
+
private RemoteWebDriver performLogin() {
RemoteWebDriver driver = chrome.getWebDriver();
driver.get(CBIO_URL_FROM_BROWSER);
@@ -179,9 +197,11 @@ private RemoteWebDriver performLogin() {
passwordInput.sendKeys("P@ssword1");
loginButton.click();
}
+ // wait for the page to load
+ driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
return driver;
}
-
+
private boolean containerFileExists(
@Nonnull final GenericContainer container, @Nonnull String path)
throws IOException, InterruptedException {
diff --git a/src/test/resources/security/keycloak-configuration-generated.json b/src/test/resources/security/keycloak-configuration-generated.json
index b6d14734437..2bc364e9886 100644
--- a/src/test/resources/security/keycloak-configuration-generated.json
+++ b/src/test/resources/security/keycloak-configuration-generated.json
@@ -1891,6 +1891,15 @@
]
}
],
+ "roles": {
+ "client": {
+ "cbioportal": [
+ {
+ "name": "study_tcga_pub"
+ }
+ ]
+ }
+ },
"groups": [
{
"name": "PUBLIC_STUDIES",