This is an automated email from the ASF dual-hosted git repository.

thenatog pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new a4ea92ea3b NIFI-10217 Refactored Registry Spring Security Configuration
a4ea92ea3b is described below

commit a4ea92ea3bc647e5afe40790fb121948d1fee2fe
Author: exceptionfactory <[email protected]>
AuthorDate: Mon Jul 11 15:04:22 2022 -0500

    NIFI-10217 Refactored Registry Spring Security Configuration
    
    Signed-off-by: Nathan Gough <[email protected]>
    
    This closes #6196.
---
 .../web/security/NiFiRegistrySecurityConfig.java   | 147 ++++++---------------
 1 file changed, 43 insertions(+), 104 deletions(-)

diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/NiFiRegistrySecurityConfig.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/NiFiRegistrySecurityConfig.java
index 86f956fe6f..cfcc8a3a6c 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/NiFiRegistrySecurityConfig.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/NiFiRegistrySecurityConfig.java
@@ -33,28 +33,24 @@ import 
org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.authentication.AuthenticationManager;
-import 
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.authentication.ProviderManager;
 import 
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 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.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.SecurityFilterChain;
 import 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
 
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
 
 /**
- * NiFi Registry Web Api Spring security
+ * Spring Security Filter Configuration
  */
 @Configuration
 @EnableWebSecurity
 @EnableGlobalMethodSecurity(prePostEnabled = true)
-public class NiFiRegistrySecurityConfig extends WebSecurityConfigurerAdapter {
+public class NiFiRegistrySecurityConfig {
 
     private static final Logger logger = 
LoggerFactory.getLogger(NiFiRegistrySecurityConfig.class);
 
@@ -67,28 +63,32 @@ public class NiFiRegistrySecurityConfig extends 
WebSecurityConfigurerAdapter {
     @Autowired
     private Authorizer authorizer;
 
-    private final AnonymousIdentityFilter anonymousAuthenticationFilter = new 
AnonymousIdentityFilter();
-
     @Autowired
     private X509IdentityProvider x509IdentityProvider;
-    private IdentityFilter x509AuthenticationFilter;
-    private IdentityAuthenticationProvider x509AuthenticationProvider;
 
     @Autowired
     private JwtIdentityProvider jwtIdentityProvider;
-    private IdentityFilter jwtAuthenticationFilter;
-    private IdentityAuthenticationProvider jwtAuthenticationProvider;
-
-    private ResourceAuthorizationFilter resourceAuthorizationFilter;
 
-    public NiFiRegistrySecurityConfig() {
-        super(true); // disable defaults
-    }
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        http
+    @Bean
+    public SecurityFilterChain securityFilterChain(final HttpSecurity http) 
throws Exception {
+        return http
+                .addFilterBefore(x509AuthenticationFilter(), 
AnonymousAuthenticationFilter.class)
+                .addFilterBefore(jwtAuthenticationFilter(), 
AnonymousAuthenticationFilter.class)
+                // Add Resource Authorization after Spring Security but before 
Jersey Resources
+                .addFilterAfter(resourceAuthorizationFilter(), 
FilterSecurityInterceptor.class)
+                .anonymous().authenticationFilter(new 
AnonymousIdentityFilter()).and()
+                .csrf().disable()
+                .logout().disable()
                 .rememberMe().disable()
+                .requestCache().disable()
+                .servletApi().disable()
+                .securityContext().disable()
+                .sessionManagement().disable()
+                .headers()
+                    .xssProtection().and()
+                    .contentSecurityPolicy("frame-ancestors 'self'").and()
+                    
.httpStrictTransportSecurity().maxAgeInSeconds(31540000).and()
+                    .frameOptions().sameOrigin().and()
                 .authorizeRequests()
                     .antMatchers(
                             "/access/token",
@@ -101,116 +101,55 @@ public class NiFiRegistrySecurityConfig extends 
WebSecurityConfigurerAdapter {
                     .anyRequest().fullyAuthenticated()
                     .and()
                 .exceptionHandling()
-                    
.authenticationEntryPoint(http401AuthenticationEntryPoint())
-                    .and()
-                .sessionManagement()
-                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
-
-        // Apply security headers for registry API. Security headers for docs 
and UI are applied with Jetty filters in registry-core.
-        http.headers().xssProtection();
-        http.headers().contentSecurityPolicy("frame-ancestors 'self'");
-        http.headers().httpStrictTransportSecurity().maxAgeInSeconds(31540000);
-        http.headers().frameOptions().sameOrigin();
-
-        // x509
-        http.addFilterBefore(x509AuthenticationFilter(), 
AnonymousAuthenticationFilter.class);
-
-        // jwt
-        http.addFilterBefore(jwtAuthenticationFilter(), 
AnonymousAuthenticationFilter.class);
-
-        // otp
-        // todo, if needed one-time password auth filter goes here
-
-        // add an anonymous authentication filter that will populate the 
authenticated,
-        // anonymous user if no other user identity is detected earlier in the 
Spring filter chain
-        http.anonymous().authenticationFilter(anonymousAuthenticationFilter);
-
-        // After Spring Security filter chain is complete (so authentication 
is done),
-        // but before the Jersey application endpoints get the request,
-        // insert the ResourceAuthorizationFilter to do its authorization 
checks
-        http.addFilterAfter(resourceAuthorizationFilter(), 
FilterSecurityInterceptor.class);
-    }
-
-    @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws 
Exception {
-        auth
-                .authenticationProvider(x509AuthenticationProvider())
-                .authenticationProvider(jwtAuthenticationProvider());
+                    
.authenticationEntryPoint(http401AuthenticationEntryPoint()).and()
+                .build();
     }
 
-    /**
-     * Provide Authentication Manager Bean to disable unnecessary 
UserDetailsServiceAutoConfiguration
-     * @return Authentication Manager
-     * @throws Exception Thrown when failing to initialize Authentication 
Manager
-     */
     @Bean
-    @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception {
-        return super.authenticationManagerBean();
+    public AuthenticationManager authenticationManager() {
+        return new ProviderManager(x509AuthenticationProvider(), 
jwtAuthenticationProvider());
     }
 
     private IdentityFilter x509AuthenticationFilter() {
-        if (x509AuthenticationFilter == null) {
-            x509AuthenticationFilter = new 
IdentityFilter(x509IdentityProvider);
-        }
-        return x509AuthenticationFilter;
+        return new IdentityFilter(x509IdentityProvider);
     }
 
     private IdentityAuthenticationProvider x509AuthenticationProvider() {
-        if (x509AuthenticationProvider == null) {
-            x509AuthenticationProvider = new 
X509IdentityAuthenticationProvider(authorizer, x509IdentityProvider, 
identityMapper);
-        }
-        return x509AuthenticationProvider;
+        return new X509IdentityAuthenticationProvider(authorizer, 
x509IdentityProvider, identityMapper);
     }
 
     private IdentityFilter jwtAuthenticationFilter() {
-        if (jwtAuthenticationFilter == null) {
-            jwtAuthenticationFilter = new IdentityFilter(jwtIdentityProvider);
-        }
-        return jwtAuthenticationFilter;
+        return new IdentityFilter(jwtIdentityProvider);
     }
 
     private IdentityAuthenticationProvider jwtAuthenticationProvider() {
-        if (jwtAuthenticationProvider == null) {
-            jwtAuthenticationProvider = new 
IdentityAuthenticationProvider(authorizer, jwtIdentityProvider, identityMapper);
-        }
-        return jwtAuthenticationProvider;
+        return new IdentityAuthenticationProvider(authorizer, 
jwtIdentityProvider, identityMapper);
     }
 
     private ResourceAuthorizationFilter resourceAuthorizationFilter() {
-        if (resourceAuthorizationFilter == null) {
-            resourceAuthorizationFilter = ResourceAuthorizationFilter.builder()
+        return ResourceAuthorizationFilter.builder()
                     .setAuthorizationService(authorizationService)
                     .addResourceType(ResourceType.Actuator)
                     .addResourceType(ResourceType.Swagger)
                     .build();
-        }
-        return resourceAuthorizationFilter;
     }
 
     private AuthenticationEntryPoint http401AuthenticationEntryPoint() {
         // This gets used for both secured and unsecured configurations. It 
will be called by Spring Security if a request makes it through the filter 
chain without being authenticated.
         // For unsecured, this should never be reached because the custom 
AnonymousAuthenticationFilter should always populate a fully-authenticated 
anonymous user
         // For secured, this will cause attempt to access any API endpoint 
(except those explicitly ignored) without providing credentials to return a 401 
Unauthorized challenge
-        return new AuthenticationEntryPoint() {
-            @Override
-            public void commence(HttpServletRequest request,
-                                 HttpServletResponse response,
-                                 AuthenticationException 
authenticationException)
-                    throws IOException {
-
-                // return a 401 response
-                final int status = HttpServletResponse.SC_UNAUTHORIZED;
-                logger.info("Client could not be authenticated due to: {} 
Returning 401 response.", authenticationException.toString());
-                logger.debug("", authenticationException);
-
-                if (!response.isCommitted()) {
-                    response.setStatus(status);
-                    response.setContentType("text/plain");
-                    response.getWriter().println(String.format("%s Contact the 
system administrator.", authenticationException.getLocalizedMessage()));
-                }
+        return (request, response, authenticationException) -> {
+
+            // return a 401 response
+            final int status = HttpServletResponse.SC_UNAUTHORIZED;
+            logger.info("Client could not be authenticated due to: {} 
Returning 401 response.", authenticationException.toString());
+            logger.debug("", authenticationException);
+
+            if (!response.isCommitted()) {
+                response.setStatus(status);
+                response.setContentType("text/plain");
+                response.getWriter().println(String.format("%s Contact the 
system administrator.", authenticationException.getLocalizedMessage()));
             }
         };
     }
-
 }

Reply via email to