From 5ad3cfdd07a72559ef8b91646a1252d0385c45c4 Mon Sep 17 00:00:00 2001 From: Dimitrios Kaitantzidis Date: Mon, 21 Oct 2024 20:45:30 +0300 Subject: [PATCH] login shows properly in keycloak, need to fix Xbool error for attributes extracting after successful login --- .../security/SecurityConfiguration.java | 33 ++++++++++++++++--- ...mSaml2ResponseAuthenticationConverter.java | 21 +++++++----- .../SPDF/model/ApplicationProperties.java | 9 +++++ src/main/resources/application.properties | 4 ++- src/main/resources/settings.yml.template | 21 ++++++------ 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index cc2eea45..57d384e4 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.security.saml2.provider.service.authentication.OpenSa import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations; import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -397,17 +398,41 @@ public class SecurityConfiguration { Saml2X509Credential verificationCredential = Saml2X509Credential.verification(idpCert); RelyingPartyRegistration rp = - RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId()) + RelyingPartyRegistrations.fromMetadataLocation(samlConf.getIdpMetadataUriString()) + .entityId(samlConf.getEntityId()) + .registrationId(samlConf.getRegistrationId()) .signingX509Credentials((c) -> c.add(signingCredential)) + .singleLogoutServiceLocation(samlConf.getIdpSingleLogoutUrl()) .assertingPartyDetails( (details) -> - details.entityId(samlConf.getIdpIssuer()) - .singleSignOnServiceLocation( - samlConf.getIdpSingleLoginUrl()) + details + // + // .entityId(samlConf.getIdpIssuer()) + // + // .singleSignOnServiceLocation( + // + // samlConf.getIdpSingleLoginUrl()) .verificationX509Credentials( (c) -> c.add(verificationCredential)) .wantAuthnRequestsSigned(true)) .build(); + + /* + RelyingPartyRegistration rp = + RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId()) + .entityId(samlConf.getEntityId()) + .signingX509Credentials((c) -> c.add(signingCredential)) + .assertingPartyDetails( + (details) -> + details.entityId(samlConf.getEntityId()) + .singleSignOnServiceLocation( + samlConf.getIdpSingleLoginUrl()) + .verificationX509Credentials( + (c) -> c.add(verificationCredential)) + .wantAuthnRequestsSigned(true)) + .build(); + + */ return new InMemoryRelyingPartyRegistrationRepository(rp); } diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java index b447eb89..6f11e61f 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java +++ b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java @@ -70,16 +70,21 @@ public class CustomSaml2ResponseAuthenticationConverter private Map> extractAttributes(Assertion assertion) { Map> attributes = new HashMap<>(); - for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) { - for (Attribute attribute : attributeStatement.getAttributes()) { - String attributeName = attribute.getName(); - List values = new ArrayList<>(); - for (XMLObject xmlObject : attribute.getAttributeValues()) { - log.info("BOOL: " + ((XSBoolean) xmlObject).getValue()); - values.add(((XSString) xmlObject).getValue()); + try { + for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) { + for (Attribute attribute : attributeStatement.getAttributes()) { + String attributeName = attribute.getName(); + List values = new ArrayList<>(); + for (XMLObject xmlObject : attribute.getAttributeValues()) { + log.info("BOOL: " + ((XSBoolean) xmlObject).getValue()); + values.add(((XSString) xmlObject).getValue()); + } + attributes.put(attributeName, values); } - attributes.put(attributeName, values); } + } catch (Exception ex) { + log.error("Could not extract attributes. Error: " + ex.getMessage()); + return attributes; } return attributes; } diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 16397965..76e17e75 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -124,6 +124,7 @@ public class ApplicationProperties { private Boolean enabled = false; private Boolean autoCreateUser = false; private Boolean blockRegistration = false; + private String entityId = "stirling"; private String registrationId = "stirling"; private String idpMetadataUri; private String idpSingleLogoutUrl; @@ -149,6 +150,10 @@ public class ApplicationProperties { } } + public String getIdpMetadataUriString() { + return this.idpMetadataUri; + } + public Resource getSpCert() { if (spCert.startsWith("classpath:")) { return new ClassPathResource(spCert.substring("classpath:".length())); @@ -172,6 +177,10 @@ public class ApplicationProperties { return new FileSystemResource(privateKey); } } + + public String getEntityId() { + return entityId; + } } @Data diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0f957c0a..e8d4ae26 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -50,4 +50,6 @@ springdoc.swagger-ui.url=/v1/api-docs posthog.api.key=phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq -posthog.host=https://eu.i.posthog.com \ No newline at end of file +posthog.host=https://eu.i.posthog.com + +server.port=8090 \ No newline at end of file diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 3ee1b928..bb697603 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -12,7 +12,7 @@ security: - enableLogin: false # set to 'true' to enable login + enableLogin: true # set to 'true' to enable login csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production) loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1 loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts @@ -48,17 +48,18 @@ security: scopes: openid, profile, email # Specify the scopes for which the application will request permissions provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' saml2: - enabled: false + enabled: true autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin - registrationId: stirling - idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata - idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml - idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml - idpIssuer: http://www.okta.com/externalKey - idpCert: classpath:octa.crt - privateKey: classpath:saml-private-key.key - spCert: classpath:saml-public-cert.crt + entityId: 'spring-boot-app' + registrationId: 'keycloak' + idpMetadataUri: 'http://localhost:8080/realms/saml-sso/protocol/saml/descriptor' + idpSingleLogoutUrl: 'http://localhost:8080/realms/saml-sso/protocol/saml' + idpSingleLoginUrl: 'http://localhost:8080/realms/saml-sso/protocol/saml' + idpIssuer: 'http://localhost:8080/realms/saml-sso' + idpCert: 'classpath:saml-public-cert.crt' + privateKey: 'classpath:local.key' + spCert: 'classpath:local.crt' # Enterprise edition settings unused for now please ignore! enterpriseEdition: