1

This works in Spring Boot:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure (final HttpSecurity http) throws Exception
    {
        http
            .csrf    ()
            .disable ()
            .authorizeRequests ()
            .antMatchers ("/public/**") .permitAll ()
            ...

This doesn't:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure (final HttpSecurity http) throws Exception
    {
        ExpressionInterceptUrlRegistry registry = http
                .csrf    ()
                .disable ()
                .authorizeRequests ();

        registry.antMatchers ("/public/**") .permitAll ();

The compilation error is

cannot find symbol
    symbol:   method permitAll()
    location: class java.lang.Object

When the chain of builder calls is split like this, antMatchers returns Object instead of ExpressionInterceptUrlRegistry? Why?

Practical question: How do I store the builder object when a chain is half-built and continue it with subsequent calls?

Theory question: Why can't the compiler see the type?

spraff
  • 32,570
  • 22
  • 121
  • 229

1 Answers1

-1

The complete theory is answered here (see below for your specific case):

Your compiler or IDE should've given you a warning. Essentially, ExpressionInterceptUrlRegistry is an inner class and its enclosing class, ExpressionUrlAuthorizationConfigurer, is generic. An inner class type is always tied to its enclosing type (and its parameterization).

Because you've declared your ExpressionInterceptUrlRegistry variable without qualifying it with its enclosing type (and without a type argument), it's considered to be of the raw ExpressionInterceptUrlRegistry type, and all generics are erased (ie. antMatchers has a return type of Object rather than whatever C should've been bound to) as explained in that canonical post about raw types I linked above.

Qualify your type appropriately with its parameterized enclosing type

ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.csrf().disable().authorizeRequests();
Savior
  • 3,225
  • 4
  • 24
  • 48