From a0a0a93a879bc6dfd25b83a80cd3bb0f5cbda5fe Mon Sep 17 00:00:00 2001 From: d036670 Date: Tue, 14 May 2024 19:46:07 +0200 Subject: [PATCH] revert and allow test endpoint again --- .../provider/IdentityProviderEndpoints.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProviderEndpoints.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProviderEndpoints.java index 4a1d54e923f..48548ec9456 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProviderEndpoints.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProviderEndpoints.java @@ -19,20 +19,29 @@ import static org.cloudfoundry.identity.uaa.constants.OriginKeys.SAML; import static org.cloudfoundry.identity.uaa.constants.OriginKeys.UAA; import static org.cloudfoundry.identity.uaa.util.UaaStringUtils.getCleanedUserControlString; +import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.CONFLICT; import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.EXPECTATION_FAILED; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; import static org.springframework.util.StringUtils.hasText; +import static org.springframework.web.bind.annotation.RequestMethod.POST; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Date; import java.util.List; import java.util.Optional; import org.cloudfoundry.identity.uaa.alias.EntityAliasFailedException; import org.cloudfoundry.identity.uaa.audit.event.EntityDeletedEvent; +import org.cloudfoundry.identity.uaa.authentication.manager.DynamicLdapAuthenticationManager; +import org.cloudfoundry.identity.uaa.authentication.manager.LdapLoginAuthenticationManager; import org.cloudfoundry.identity.uaa.provider.saml.SamlIdentityProviderConfigurator; +import org.cloudfoundry.identity.uaa.scim.ScimGroupExternalMembershipManager; +import org.cloudfoundry.identity.uaa.scim.ScimGroupProvisioning; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.ObjectUtils; import org.cloudfoundry.identity.uaa.zone.beans.IdentityZoneManager; @@ -47,7 +56,10 @@ import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.InternalAuthenticationServiceException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; @@ -73,6 +85,9 @@ public class IdentityProviderEndpoints implements ApplicationEventPublisherAware @Value("${login.aliasEntitiesEnabled:false}") private boolean aliasEntitiesEnabled; private final IdentityProviderProvisioning identityProviderProvisioning; + private final ScimGroupExternalMembershipManager scimGroupExternalMembershipManager; + private final ScimGroupProvisioning scimGroupProvisioning; + private final NoOpLdapLoginAuthenticationManager noOpManager = new NoOpLdapLoginAuthenticationManager(); private final SamlIdentityProviderConfigurator samlConfigurator; private final IdentityProviderConfigValidator configValidator; private final IdentityZoneManager identityZoneManager; @@ -88,6 +103,8 @@ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEv public IdentityProviderEndpoints( final @Qualifier("identityProviderProvisioning") IdentityProviderProvisioning identityProviderProvisioning, + final @Qualifier("externalGroupMembershipManager") ScimGroupExternalMembershipManager scimGroupExternalMembershipManager, + final @Qualifier("scimGroupProvisioning") ScimGroupProvisioning scimGroupProvisioning, final @Qualifier("metaDataProviders") SamlIdentityProviderConfigurator samlConfigurator, final @Qualifier("identityProviderConfigValidator") IdentityProviderConfigValidator configValidator, final IdentityZoneManager identityZoneManager, @@ -95,6 +112,8 @@ public IdentityProviderEndpoints( final IdentityProviderAliasHandler idpAliasHandler ) { this.identityProviderProvisioning = identityProviderProvisioning; + this.scimGroupExternalMembershipManager = scimGroupExternalMembershipManager; + this.scimGroupProvisioning = scimGroupProvisioning; this.samlConfigurator = samlConfigurator; this.configValidator = configValidator; this.identityZoneManager = identityZoneManager; @@ -288,6 +307,40 @@ public ResponseEntity retrieveIdentityProvider(@PathVariable S return new ResponseEntity<>(identityProvider, OK); } + @RequestMapping(value = "test", method = POST) + public ResponseEntity testIdentityProvider(@RequestBody IdentityProviderValidationRequest body) { + String exception = "ok"; + HttpStatus status = OK; + //create the LDAP IDP + DynamicLdapAuthenticationManager manager = new DynamicLdapAuthenticationManager( + ObjectUtils.castInstance(body.getProvider().getConfig(),LdapIdentityProviderDefinition.class), + scimGroupExternalMembershipManager, + scimGroupProvisioning, + noOpManager + ); + try { + //attempt authentication + Authentication result = manager.authenticate(body.getCredentials()); + if ((result == null) || (result != null && !result.isAuthenticated())) { + status = EXPECTATION_FAILED; + } + } catch (BadCredentialsException x) { + status = EXPECTATION_FAILED; + exception = "bad credentials"; + } catch (InternalAuthenticationServiceException x) { + status = BAD_REQUEST; + exception = getExceptionString(x); + } catch (Exception x) { + logger.error("Identity provider validation failed.", x); + status = INTERNAL_SERVER_ERROR; + exception = "check server logs"; + }finally { + //destroy IDP + manager.destroy(); + } + //return results + return new ResponseEntity<>(JsonUtils.writeValueAsString(exception), status); + } @ExceptionHandler(MetadataProviderException.class) public ResponseEntity handleMetadataProviderException(MetadataProviderException e) { @@ -308,6 +361,24 @@ public ResponseEntity handleProviderNotFoundException() { return new ResponseEntity<>("Provider not found.", HttpStatus.NOT_FOUND); } + + protected String getExceptionString(Exception x) { + StringWriter writer = new StringWriter(); + x.printStackTrace(new PrintWriter(writer)); + return writer.getBuffer().toString(); + } + + protected static class NoOpLdapLoginAuthenticationManager extends LdapLoginAuthenticationManager { + public NoOpLdapLoginAuthenticationManager() { + super(null); + } + + @Override + public Authentication authenticate(Authentication request) throws AuthenticationException { + return request; + } + } + protected void patchSensitiveData(String id, IdentityProvider provider) { String zoneId = identityZoneManager.getCurrentIdentityZoneId(); if (provider.getConfig() == null) {