grails-spring-security-core icon indicating copy to clipboard operation
grails-spring-security-core copied to clipboard

How to wire in custom WebSecurityConfigurer in grails 5

Open ShurikAg opened this issue 3 years ago • 8 comments

Issue description

I decided to post here, as I am not getting anything from the Stackoverflow post.

As part of moving our environments to Kubernetes, we are using Ambassador as the ingress service. The app itself (the API side) is using Grails spring-security plugin. Having these two together, the preflight requests are not passing as the implementation will deny these requests. (see: https://www.getambassador.io/docs/edge-stack/latest/topics/using/cors/#authservice-and-cross-origin-resource-sharing).

I was digging for a solution for quite some time now, and the one that stands out in many places is to create a custom WebSecurityConfigurer (also, as suggested by Ambassador).

We I created the following:

package priz.api.security

import grails.compiler.GrailsCompileStatic
import org.springframework.boot.autoconfigure.security.SecurityProperties
import org.springframework.context.annotation.Configuration
import org.springframework.core.annotation.Order
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.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource

import javax.servlet.http.HttpServletRequest

@GrailsCompileStatic
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.DEFAULT_FILTER_ORDER)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    public void configure(final HttpSecurity http) throws Exception {
        http
                .cors().configurationSource(new PermissiveCorsConfigurationSource()).and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("**").permitAll();
    }

    private static class PermissiveCorsConfigurationSource implements CorsConfigurationSource {
        /**
         * Return a {@link CorsConfiguration} based on the incoming request.
         *
         * @param request
         * @return the associated {@link CorsConfiguration}, or {@code null} if none
         */
        @Override
        public CorsConfiguration getCorsConfiguration(final HttpServletRequest request) {
            final CorsConfiguration configuration = new CorsConfiguration();
            configuration.setAllowCredentials(true);
            configuration.setAllowedHeaders(Collections.singletonList("*"));
            configuration.setAllowedMethods(Collections.singletonList("*"));
            configuration.setAllowedOrigins(Collections.singletonList("*"));
            return configuration;
        }
    }
}

However, this config is not getting picked up. Is there anything additional that I have to do to register it? My expectation was that the annotations are taking care of that. Also tried @EnableGlobalMethodSecurity instead, the same result.

Thanks for the advice.

I could also create an interceptor, but Grails interceptors cannot intercept the endpoints provided by the Spring Security core/rest plugins since the priority of their interceptors are higher than that of Grails interceptors

ShurikAg avatar Jan 27 '22 19:01 ShurikAg