diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml index 5a9de06417c9..dc54975cc8e0 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml @@ -207,32 +207,28 @@ org.springframework.security spring-security-saml2-service-provider - + - org.apache.velocity - velocity - - - org.bouncycastle - bcprov-jdk15on + org.opensaml + opensaml-core org.opensaml - opensaml-core + opensaml-core-api org.opensaml - opensaml-xmlsec-api + opensaml-core-impl - com.nimbusds - nimbus-jose-jwt + org.opensaml + opensaml-saml-api org.opensaml - opensaml-saml-api + opensaml-saml-impl diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/ClientRegistrationConfiguration.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/ClientRegistrationConfiguration.java index 3d3ac1d63b26..0a283801c1d9 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/ClientRegistrationConfiguration.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/ClientRegistrationConfiguration.java @@ -34,7 +34,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; -import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestClient; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; @@ -75,7 +75,7 @@ public ClientRegistrationConfiguration( public ClientRegistrationRepository clientRegistrationRepository() { final ClientRegistrationRepository clientRegistrationRepository; if (properties.isOidcEnabled()) { - final ClientRegistrationProvider clientRegistrationProvider = new StandardClientRegistrationProvider(properties, oidcRestOperations()); + final ClientRegistrationProvider clientRegistrationProvider = new StandardClientRegistrationProvider(properties, oidcRestClient()); final ClientRegistration clientRegistration = clientRegistrationProvider.getClientRegistration(); clientRegistrationRepository = new InMemoryClientRegistrationRepository(clientRegistration); } else { @@ -84,6 +84,15 @@ public ClientRegistrationRepository clientRegistrationRepository() { return clientRegistrationRepository; } + /** + * OpenID Connect REST Client for communication with Authorization Servers + * + * @return REST Client + */ + @Bean + public RestClient oidcRestClient() { + return RestClient.create(oidcRestOperations()); + } /** * OpenID Connect REST Operations for communication with Authorization Servers @@ -91,7 +100,7 @@ public ClientRegistrationRepository clientRegistrationRepository() { * @return REST Operations */ @Bean - public RestOperations oidcRestOperations() { + public RestTemplate oidcRestOperations() { final RestTemplate restTemplate = new RestTemplate(oidcClientHttpRequestFactory()); restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); restTemplate.setMessageConverters( diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/OidcSecurityConfiguration.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/OidcSecurityConfiguration.java index b4f13ec91c98..7b3db23347e0 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/OidcSecurityConfiguration.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/OidcSecurityConfiguration.java @@ -49,10 +49,10 @@ import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient; -import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; +import org.springframework.security.oauth2.client.endpoint.RestClientAuthorizationCodeTokenResponseClient; +import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient; import org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; import org.springframework.security.oauth2.client.registration.ClientRegistration; @@ -71,6 +71,7 @@ import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.web.client.RestClient; import org.springframework.web.client.RestOperations; import java.time.Duration; @@ -110,6 +111,8 @@ public class OidcSecurityConfiguration { private final RestOperations oidcRestOperations; + private final RestClient oidcRestClient; + private final LogoutRequestManager logoutRequestManager; @Autowired @@ -124,6 +127,8 @@ public OidcSecurityConfiguration( final JwtDecoderFactory idTokenDecoderFactory, @Qualifier("oidcRestOperations") final RestOperations oidcRestOperations, + @Qualifier("oidcRestClient") + final RestClient oidcRestClient, final LogoutRequestManager logoutRequestManager ) { this.properties = Objects.requireNonNull(properties, "Properties required"); @@ -135,6 +140,7 @@ public OidcSecurityConfiguration( this.jwtDecoder = Objects.requireNonNull(jwtDecoder, "JWT Decoder required"); this.idTokenDecoderFactory = Objects.requireNonNull(idTokenDecoderFactory, "ID Token Decoder Factory required"); this.oidcRestOperations = Objects.requireNonNull(oidcRestOperations, "OIDC REST Operations required"); + this.oidcRestClient = Objects.requireNonNull(oidcRestClient, "OIDC Rest Client required"); this.logoutRequestManager = Objects.requireNonNull(logoutRequestManager, "Logout Request Manager required"); this.keyRotationPeriod = properties.getSecurityUserJwsKeyRotationPeriod(); } @@ -207,8 +213,8 @@ public OAuth2LoginAuthenticationFilter oAuth2LoginAuthenticationFilter(final Aut */ @Bean public OidcBearerTokenRefreshFilter oidcBearerTokenRefreshFilter() { - final DefaultRefreshTokenTokenResponseClient refreshTokenResponseClient = new DefaultRefreshTokenTokenResponseClient(); - refreshTokenResponseClient.setRestOperations(oidcRestOperations); + final RestClientRefreshTokenTokenResponseClient refreshTokenResponseClient = new RestClientRefreshTokenTokenResponseClient(); + refreshTokenResponseClient.setRestClient(oidcRestClient); final String refreshWindowProperty = properties.getOidcTokenRefreshWindow(); final double refreshWindowSeconds = FormatUtils.getPreciseTimeDuration(refreshWindowProperty, TimeUnit.SECONDS); @@ -271,9 +277,9 @@ public OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenti */ @Bean public OAuth2AccessTokenResponseClient accessTokenResponseClient() { - final DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient(); - accessTokenResponseClient.setRestOperations(oidcRestOperations); - return accessTokenResponseClient; + final RestClientAuthorizationCodeTokenResponseClient tokenResponseClient = new RestClientAuthorizationCodeTokenResponseClient(); + tokenResponseClient.setRestClient(oidcRestClient); + return tokenResponseClient; } /** diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/SamlAuthenticationSecurityConfiguration.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/SamlAuthenticationSecurityConfiguration.java index 27a8095480af..55052a6c9e20 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/SamlAuthenticationSecurityConfiguration.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/SamlAuthenticationSecurityConfiguration.java @@ -25,7 +25,6 @@ import org.apache.nifi.web.security.jwt.provider.BearerTokenProvider; import org.apache.nifi.web.security.logout.LogoutRequestManager; import org.apache.nifi.web.security.saml2.SamlUrlPath; -import org.apache.nifi.web.security.saml2.registration.EntityDescriptorCustomizer; import org.apache.nifi.web.security.saml2.service.authentication.ResponseAuthenticationConverter; import org.apache.nifi.web.security.saml2.registration.Saml2RegistrationProperty; import org.apache.nifi.web.security.saml2.service.web.StandardRelyingPartyRegistrationResolver; @@ -44,26 +43,26 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest; -import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; -import org.springframework.security.saml2.provider.service.authentication.logout.OpenSamlLogoutRequestValidator; -import org.springframework.security.saml2.provider.service.authentication.logout.OpenSamlLogoutResponseValidator; +import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider; +import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml5LogoutRequestValidator; +import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml5LogoutResponseValidator; import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutRequestValidator; import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutResponseValidator; -import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; +import org.springframework.security.saml2.provider.service.metadata.OpenSaml5MetadataResolver; import org.springframework.security.saml2.provider.service.metadata.Saml2MetadataResolver; 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.web.authentication.OpenSaml5AuthenticationRequestResolver; import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter; import org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter; import org.springframework.security.saml2.provider.service.web.Saml2MetadataFilter; -import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver; -import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutRequestResolver; -import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutResponseResolver; +import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml5LogoutRequestResolver; +import org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml5LogoutResponseResolver; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestFilter; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestRepository; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestResolver; @@ -222,11 +221,11 @@ public Saml2LocalLogoutFilter saml2LocalLogoutFilter() { /** * Spring Security OpenSAML Authentication Provider for processing SAML 2 login responses * - * @return OpenSAML 4 Authentication Provider compatible with Java 11 + * @return OpenSAML Authentication Provider */ @Bean - public OpenSaml4AuthenticationProvider openSamlAuthenticationProvider() { - final OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider(); + public OpenSaml5AuthenticationProvider openSamlAuthenticationProvider() { + final OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider(); final ResponseAuthenticationConverter responseAuthenticationConverter = new ResponseAuthenticationConverter(properties.getSamlGroupAttributeName()); provider.setResponseAuthenticationConverter(responseAuthenticationConverter); return provider; @@ -235,11 +234,11 @@ public OpenSaml4AuthenticationProvider openSamlAuthenticationProvider() { /** * Spring Security SAML 2 Authentication Request Resolver uses OpenSAML 4 * - * @return OpenSAML 4 version of SAML 2 Authentication Request Resolver + * @return OpenSAML SAML 2 Authentication Request Resolver */ @Bean public Saml2AuthenticationRequestResolver saml2AuthenticationRequestResolver() { - return new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationResolver()); + return new OpenSaml5AuthenticationRequestResolver(relyingPartyRegistrationResolver()); } /** @@ -249,7 +248,7 @@ public Saml2AuthenticationRequestResolver saml2AuthenticationRequestResolver() { */ @Bean public Saml2LogoutRequestValidator saml2LogoutRequestValidator() { - return new OpenSamlLogoutRequestValidator(); + return new OpenSaml5LogoutRequestValidator(); } /** @@ -259,27 +258,27 @@ public Saml2LogoutRequestValidator saml2LogoutRequestValidator() { */ @Bean public Saml2LogoutResponseValidator saml2LogoutResponseValidator() { - return new OpenSamlLogoutResponseValidator(); + return new OpenSaml5LogoutResponseValidator(); } /** * Spring Security SAML 2 Logout Request Resolver uses OpenSAML 4 * - * @return OpenSAML 4 version of SAML 2 Logout Request Resolver + * @return OpenSAML SAML 2 Logout Request Resolver */ @Bean public Saml2LogoutRequestResolver saml2LogoutRequestResolver() { - return new OpenSaml4LogoutRequestResolver(relyingPartyRegistrationResolver()); + return new OpenSaml5LogoutRequestResolver(relyingPartyRegistrationResolver()); } /** * Spring Security SAML 2 Logout Response Resolver uses OpenSAML 4 * - * @return OpenSAML 4 version of SAML 2 Logout Response Resolver + * @return OpenSAML SAML 2 Logout Response Resolver */ @Bean public Saml2LogoutResponseResolver saml2LogoutResponseResolver() { - return new OpenSaml4LogoutResponseResolver(relyingPartyRegistrationResolver()); + return new OpenSaml5LogoutResponseResolver(relyingPartyRegistrationResolver()); } /** @@ -326,12 +325,8 @@ public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { */ @Bean public Saml2MetadataResolver saml2MetadataResolver() { - final OpenSamlMetadataResolver resolver = new OpenSamlMetadataResolver(); - final EntityDescriptorCustomizer customizer = new EntityDescriptorCustomizer( - properties.isSamlWantAssertionsSigned(), - properties.isSamlRequestSigningEnabled() - ); - resolver.setEntityDescriptorCustomizer(customizer); + final OpenSaml5MetadataResolver resolver = new OpenSaml5MetadataResolver(); + resolver.setSignMetadata(properties.isSamlRequestSigningEnabled()); return resolver; } @@ -395,9 +390,9 @@ private RelyingPartyRegistrationRepository getDisabledRelyingPartyRegistrationRe final RelyingPartyRegistration registration = RelyingPartyRegistration .withRegistrationId(Saml2RegistrationProperty.REGISTRATION_ID.getProperty()) .entityId(Saml2RegistrationProperty.REGISTRATION_ID.getProperty()) - .assertingPartyDetails(assertingPartyDetails -> { - assertingPartyDetails.entityId(Saml2RegistrationProperty.REGISTRATION_ID.getProperty()); - assertingPartyDetails.singleSignOnServiceLocation(SamlUrlPath.LOGIN_RESPONSE_REGISTRATION_ID.getPath()); + .assertingPartyMetadata(assertingPartyMetadata -> { + assertingPartyMetadata.entityId(Saml2RegistrationProperty.REGISTRATION_ID.getProperty()); + assertingPartyMetadata.singleSignOnServiceLocation(SamlUrlPath.LOGIN_RESPONSE_REGISTRATION_ID.getPath()); }) .build(); return new InMemoryRelyingPartyRegistrationRepository(registration); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/authentication/StandardOidcIdTokenDecoderFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/authentication/StandardOidcIdTokenDecoderFactory.java index 22389f468f21..e4f946e5919c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/authentication/StandardOidcIdTokenDecoderFactory.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/authentication/StandardOidcIdTokenDecoderFactory.java @@ -38,8 +38,6 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; import java.util.Objects; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -54,15 +52,11 @@ public class StandardOidcIdTokenDecoderFactory implements JwtDecoderFactory SECRET_KEY_ALGORITHMS; - - static { - final Map mappings = new HashMap<>(); - mappings.put(MacAlgorithm.HS256, "HmacSHA256"); - mappings.put(MacAlgorithm.HS384, "HmacSHA384"); - mappings.put(MacAlgorithm.HS512, "HmacSHA512"); - SECRET_KEY_ALGORITHMS = Collections.unmodifiableMap(mappings); - } + private static final Map SECRET_KEY_ALGORITHMS = Map.of( + MacAlgorithm.HS256, "HmacSHA256", + MacAlgorithm.HS384, "HmacSHA384", + MacAlgorithm.HS512, "HmacSHA512" + ); private static final ClaimTypeConverter DEFAULT_CLAIM_TYPE_CONVERTER = new ClaimTypeConverter( OidcIdTokenDecoderFactory.createDefaultClaimTypeConverters() diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOidcAuthorizedClientRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOidcAuthorizedClientRepository.java index 76a3e071b99f..816069f3c80a 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOidcAuthorizedClientRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOidcAuthorizedClientRepository.java @@ -205,11 +205,9 @@ private OidcAuthorizedClient getOidcAuthorizedClient(final OAuth2AuthorizedClien private OidcIdToken getOidcIdToken(final Authentication authentication) { final OidcIdToken oidcIdToken; - if (authentication instanceof OAuth2AuthenticationToken) { - final OAuth2AuthenticationToken authenticationToken = (OAuth2AuthenticationToken) authentication; + if (authentication instanceof OAuth2AuthenticationToken authenticationToken) { final OAuth2User oAuth2User = authenticationToken.getPrincipal(); - if (oAuth2User instanceof OidcUser) { - final OidcUser oidcUser = (OidcUser) oAuth2User; + if (oAuth2User instanceof OidcUser oidcUser) { oidcIdToken = oidcUser.getIdToken(); } else { final String message = String.format("OpenID Connect User not found [%s]", oAuth2User.getClass()); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java index c24b10649091..40491d1085be 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java @@ -31,7 +31,7 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcScopes; -import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestClient; import java.util.Arrays; import java.util.Collections; @@ -53,14 +53,14 @@ public class StandardClientRegistrationProvider implements ClientRegistrationPro private final NiFiProperties properties; - private final RestOperations restOperations; + private final RestClient restClient; public StandardClientRegistrationProvider( final NiFiProperties properties, - final RestOperations restOperations + final RestClient restClient ) { this.properties = Objects.requireNonNull(properties, "Properties required"); - this.restOperations = Objects.requireNonNull(restOperations, "REST Operations required"); + this.restClient = Objects.requireNonNull(restClient, "REST Client required"); } /** @@ -110,7 +110,7 @@ private OIDCProviderMetadata getProviderMetadata() { final String metadataObject; try { - metadataObject = restOperations.getForObject(discoveryUrl, String.class); + metadataObject = restClient.get().uri(discoveryUrl).retrieve().body(String.class); } catch (final RuntimeException e) { final String message = String.format("OpenID Connect Metadata URL [%s] retrieval failed", discoveryUrl); throw new OidcConfigurationException(message, e); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/EntityDescriptorCustomizer.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/EntityDescriptorCustomizer.java deleted file mode 100644 index 11f1d36954e7..000000000000 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/EntityDescriptorCustomizer.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.nifi.web.security.saml2.registration; - -import org.opensaml.saml.common.xml.SAMLConstants; -import org.opensaml.saml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml.saml2.metadata.SPSSODescriptor; -import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; - -import java.util.function.Consumer; - -/** - * Entity Descriptor Customizer sets configuration properties - */ -public class EntityDescriptorCustomizer implements Consumer { - private boolean wantAssertionsSigned; - - private boolean requestsSigned; - - /** - * Entity Descriptor Customizer with configuration properties - * - * @param wantAssertionsSigned Enable or disable indication of want assertions signed on SP SSO Descriptor - * @param requestsSigned Enable or disable indication of authentication requests signed on SP SSO Descriptor - */ - public EntityDescriptorCustomizer( - final boolean wantAssertionsSigned, - final boolean requestsSigned - ) { - this.wantAssertionsSigned = wantAssertionsSigned; - this.requestsSigned = requestsSigned; - } - - @Override - public void accept(final OpenSamlMetadataResolver.EntityDescriptorParameters entityDescriptorParameters) { - final EntityDescriptor entityDescriptor = entityDescriptorParameters.getEntityDescriptor(); - final SPSSODescriptor spssoDescriptor = entityDescriptor.getSPSSODescriptor(SAMLConstants.SAML20P_NS); - spssoDescriptor.setWantAssertionsSigned(wantAssertionsSigned); - spssoDescriptor.setAuthnRequestsSigned(requestsSigned); - } -} diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/StandardRelyingPartyRegistrationRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/StandardRelyingPartyRegistrationRepository.java index f5a62aea31a7..1db70a9d02be 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/StandardRelyingPartyRegistrationRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/registration/StandardRelyingPartyRegistrationRepository.java @@ -111,7 +111,7 @@ private RelyingPartyRegistration getRelyingPartyRegistration() { .toList(); logger.debug("Loaded SAML2 Verification Credentials [{}]", verificationCredentials.size()); - builder.assertingPartyDetails(assertingPartyDetails -> assertingPartyDetails + builder.assertingPartyMetadata(assertingPartyMetadata -> assertingPartyMetadata .signingAlgorithms(signingAlgorithms -> signingAlgorithms.add(properties.getSamlSignatureAlgorithm())) .verificationX509Credentials(credentials -> credentials.addAll(verificationCredentials)) .encryptionX509Credentials(credentials -> credentials.addAll(verificationCredentials)) diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/authentication/ResponseAuthenticationConverter.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/authentication/ResponseAuthenticationConverter.java index f3a38d8ac714..632632e5e0ba 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/authentication/ResponseAuthenticationConverter.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/authentication/ResponseAuthenticationConverter.java @@ -24,8 +24,8 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; -import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken; +import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider; +import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider.ResponseToken; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; @@ -39,7 +39,7 @@ * Converter from SAML 2 Response Token to SAML 2 Authentication for Spring Security */ public class ResponseAuthenticationConverter implements Converter { - private static final Converter defaultConverter = OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter(); + private static final Converter defaultConverter = OpenSaml5AuthenticationProvider.createDefaultResponseAuthenticationConverter(); private final String groupAttributeName; @@ -91,11 +91,9 @@ private Collection getAuthorities(final List { - private String attributeName; + private final String attributeName; public AttributeNameIdentityConverter(final String attributeName) { this.attributeName = Objects.requireNonNull(attributeName, "Attribute Name required"); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java index c478dfa094a7..896d3f81945e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java @@ -29,7 +29,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; -import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestClient; import java.net.URI; import java.util.Arrays; @@ -43,6 +43,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -70,17 +72,26 @@ class StandardClientRegistrationProviderTest { private static final String INVALID_CONFIGURATION = "{}"; @Mock - RestOperations restOperations; + RestClient restClient; + + @Mock + RestClient.RequestHeadersUriSpec requestHeadersUriSpec; + + @Mock + RestClient.ResponseSpec responseSpec; @Test void testGetClientRegistration() { final NiFiProperties properties = getProperties(); - final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restOperations); + final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restClient); final OIDCProviderMetadata providerMetadata = getProviderMetadata(); final String serializedMetadata = providerMetadata.toString(); - when(restOperations.getForObject(eq(DISCOVERY_URL), eq(String.class))).thenReturn(serializedMetadata); + doReturn(requestHeadersUriSpec).when(restClient).get(); + doReturn(requestHeadersUriSpec).when(requestHeadersUriSpec).uri(eq(DISCOVERY_URL)); + doReturn(responseSpec).when(requestHeadersUriSpec).retrieve(); + when(responseSpec.body(eq(String.class))).thenReturn(serializedMetadata); final ClientRegistration clientRegistration = provider.getClientRegistration(); @@ -106,9 +117,11 @@ void testGetClientRegistration() { @Test void testGetClientRegistrationRetrievalFailed() { final NiFiProperties properties = getProperties(); - final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restOperations); + final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restClient); - when(restOperations.getForObject(eq(DISCOVERY_URL), eq(String.class))).thenThrow(new RuntimeException()); + doReturn(requestHeadersUriSpec).when(restClient).get(); + doReturn(requestHeadersUriSpec).when(requestHeadersUriSpec).uri(eq(DISCOVERY_URL)); + doThrow(new RuntimeException()).when(requestHeadersUriSpec).retrieve(); assertThrows(OidcConfigurationException.class, provider::getClientRegistration); } @@ -116,9 +129,12 @@ void testGetClientRegistrationRetrievalFailed() { @Test void testGetClientRegistrationParsingFailed() { final NiFiProperties properties = getProperties(); - final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restOperations); + final StandardClientRegistrationProvider provider = new StandardClientRegistrationProvider(properties, restClient); - when(restOperations.getForObject(eq(DISCOVERY_URL), eq(String.class))).thenReturn(INVALID_CONFIGURATION); + doReturn(requestHeadersUriSpec).when(restClient).get(); + doReturn(requestHeadersUriSpec).when(requestHeadersUriSpec).uri(eq(DISCOVERY_URL)); + doReturn(responseSpec).when(requestHeadersUriSpec).retrieve(); + when(responseSpec.body(eq(String.class))).thenReturn(INVALID_CONFIGURATION); assertThrows(OidcConfigurationException.class, provider::getClientRegistration); } diff --git a/nifi-framework-bundle/pom.xml b/nifi-framework-bundle/pom.xml index 73e9aed6ed8a..c622dbed5b4a 100644 --- a/nifi-framework-bundle/pom.xml +++ b/nifi-framework-bundle/pom.xml @@ -26,7 +26,7 @@ 5.7.1 33.3.1-jre - 4.3.2 + 5.1.3 nifi-framework @@ -103,8 +103,6 @@ icu4j 76.1 - - com.nimbusds oauth2-oidc-sdk @@ -113,7 +111,7 @@ com.nimbusds nimbus-jose-jwt - 9.42 + 9.47 org.codehaus.jettison @@ -263,32 +261,32 @@ - + org.opensaml - opensaml-core + opensaml-core-api ${org.opensaml.version} org.opensaml - opensaml-saml-api + opensaml-core-impl ${org.opensaml.version} org.opensaml - opensaml-saml-impl + opensaml-saml-api ${org.opensaml.version} org.opensaml - opensaml-xmlsec-api + opensaml-saml-impl ${org.opensaml.version} org.apache.santuario xmlsec - 2.3.4 + 4.0.3 com.fasterxml.woodstox diff --git a/pom.xml b/pom.xml index 45f933d36efb..41cb0b2a2c67 100644 --- a/pom.xml +++ b/pom.xml @@ -155,7 +155,7 @@ 4.1.115.Final 6.1.0 6.2.0 - 6.3.4 + 6.4.0 2.2.26 2.3.232 3.9.3