Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalStateException: Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one. #573

Open
whiskeysierra opened this issue Dec 23, 2020 · 15 comments
Labels

Comments

@whiskeysierra
Copy link
Collaborator

Description

The ProblemSecurityAutoConfiguration registers a WebSecurityConfigurerAdapter and causes this issue when combined with the spring-boot-security-starter causes spring-projects/spring-security#9295.

Expected Behavior

Exception above.

Actual Behavior

Register configurer if and only if we don't interfere with the default.

Possible Fix

Steps to Reproduce

Context

Your Environment

  • Version used:
  • Link to your project:
@whiskeysierra
Copy link
Collaborator Author

@AutoConfigureAfter(SecurityAutoConfiguration.class)

By running after, we let the defaults register a security filter chain and then we add a configurer afterwards...

@magnusheino
Copy link

Is this issue planned to go into a release soon?

@whiskeysierra
Copy link
Collaborator Author

There is no fix merged yet. Feel free to open a PR, I can quickly merge and release then.

@Monax111
Copy link

Is there a workaround to make Spring 2.4 work?

@whiskeysierra
Copy link
Collaborator Author

whiskeysierra commented Feb 12, 2021 via email

@Monax111
Copy link

how to do it? exclude some autoConfiguration or set some properties?

@whiskeysierra
Copy link
Collaborator Author

whiskeysierra commented Feb 12, 2021 via email

@Monax111
Copy link

log.txt
to be honest, I haven't even found such an auto configuration. I tried excluding SecurityAutoConfiguration. But the result is the same. Attached a log with CONDITIONS EVALUATION REPORT. Could you see what exactly I need to exclude?

@whiskeysierra
Copy link
Collaborator Author

whiskeysierra commented Feb 12, 2021 via email

@Monax111
Copy link

I'm a little confused. I have spring(2.2.4) project with Keycloak authtorization. Now i try upgrade spring to 2.4.2. I see error in console
IllegalStateException: Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.
i start serch this problem and found this issue
in down have link to this issue, and think, that you can halp me)
i don't use Problem Spring library( Excuse for troubling

@rubensa
Copy link

rubensa commented May 11, 2021

You need to exclude the problem security auto configuration.

On Fri, 12 Feb 2021, 11:08 Tim, @.***> wrote: Is there a workaround to make Spring 2.4 work? — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <#573 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADI7HM6WMPPRNYCCT5DKZDS6T43RANCNFSM4VGZU5KA .

@Monax111 you can disable ProblemSecurityAutoConfiguration by:

@EnableAutoConfiguration(exclude = ProblemSecurityAutoConfiguration.class)

But the problem then, @whiskeysierra, is that if a security exception is thrown the org.zalando.problem.spring.web.autoconfigure.ExceptionHandling#handlleThrowable(Throwable, NativeWebRequest) is invoked and produces a 500 INTERNAL_SERVER_ERROR (as the Problem implementation for Spring Security Exceptions has not been configured)

@whiskeysierra any idea on how to configure the Problem support for Spring Security but not getting the IllegalStateException: Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one?

Looks like org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration (imported from org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration) is the culprit of creating the SecurityFilterChain.

@rubensa
Copy link

rubensa commented May 11, 2021

Sample test to show the problem:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
  <groupId>org.eu.rubensa.springboot.error</groupId>
  <artifactId>springboot-error-test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springboot-error-test</name>
  <description>Project for testing Spring Boot error handling</description>
  <properties>
    <java.version>8</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

SpringSecurityExceptionTest.java

package org.eu.rubensa.springboot.error;

import com.fasterxml.jackson.databind.JsonNode;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * The {@link org.springframework.boot.test.context.SpringBootTest} annotation
 * will load the fully ApplicationContext. This will not use slicing and scan
 * for all the stereotype annotations
 * ({@link org.springframework.stereotype.Component},
 * {@link org.springframework.stereotype.Service},
 * {@link org.springframework.stereotype.Repository} and
 * {@link org.springframework.stereotype.Controller} /
 * {@link org.springframework.web.bind.annotation.RestController}) and loads the
 * full application context.
 */
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
    /**
     * When you add the Security starter without custom security configurations,
     * Spring Boot endpoints will be secured using HTTP basic authentication with a
     * default user and generated password. To override that, you can configure
     * credentials in application.properties as follows
     */
    "spring.security.user.name=username", "spring.security.user.password=password" })
public class SpringSecurityExceptionTest {
  private static final String USER_NAME = "username";
  private static final String USER_PASSWORD = "password";

  @Autowired
  private TestRestTemplate testRestTemplate;

  @Test
  public void testAccessOK() throws Exception {
    final ResponseEntity<String> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/access-ok", HttpMethod.GET, null, String.class);
    Assertions.assertThat(response.getBody()).isEqualTo("OK");
  }

  @Test
  public void testAccessDenied() throws Exception {
    final ResponseEntity<JsonNode> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/deny-all", HttpMethod.GET, null, JsonNode.class);
    Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
    JsonNode jsonResponse = response.getBody();
    Assertions.assertThat(jsonResponse.findValue("status").asInt()).isEqualTo(403);
    Assertions.assertThat(jsonResponse.findValue("error").asText()).isEqualTo("Forbidden");
    Assertions.assertThat(jsonResponse.findValue("path").asText()).isEqualTo("/deny-all");
  }

  /**
   * A single {@link org.springframework.boot.autoconfigure.SpringBootApplication}
   * annotation can be used to enable:
   * <ul>
   * <li>{@link org.springframework.boot.autoconfigure.EnableAutoConfiguration}:
   * enable Spring Boot’s auto-configuration mechanism</li>
   * <li>{@link org.springframework.context.annotation.ComponentScan}: enable
   * {@link org.springframework.stereotype.Component} scan on the package where
   * the application is located (see the best practices)</li>
   * <li>{@link org.springframework.context.annotation.Configuration}: allow to
   * register extra beans in the context or import additional configuration
   * classes</li>
   * </ul>
   * <p>
   * A nested {@link org.springframework.context.annotation.Configuration} class
   * wild be used instead of the application’s primary configuration.
   * <p>
   * Unlike a nested {@link org.springframework.context.annotation.Configuration}
   * class, which would be used instead of your application’s primary
   * configuration, a nested
   * {@link org.springframework.boot.test.context.TestConfiguration} class is used
   * in addition to your application’s primary configuration.
   */
  @Configuration
  /**
   * Tells Spring Boot to start adding beans based on classpath settings, other
   * beans, and various property settings.
   */
  @EnableAutoConfiguration
  /**
   * Provides AOP security on methods. Some of the annotations that it provides
   * are PreAuthorize, PostAuthoriz
   */
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  /**
   * The {@link org.springframework.context.annotation.ComponentScan} tells Spring
   * to look for other components, configurations, and services in the the
   * TestConfig package.
   * <p>
   * We only want to test the classes defined inside this test configuration so we
   * do nos use it here.
   */
  static class TestConfig {
    @RestController
    public static class TestController {
      @GetMapping("/access-ok")
      public @ResponseBody String getAccessOk() {
        return "OK";
      }

      @GetMapping("/deny-all")
      @PreAuthorize("denyAll()")
      public void getAccessDenied() {
      }
    }
  }
}

The tests pass.

If I add problem-spring-web:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
  <groupId>org.eu.rubensa.springboot.error</groupId>
  <artifactId>springboot-error-test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springboot-error-test</name>
  <description>Project for testing Spring Boot error handling</description>
  <properties>
    <java.version>8</java.version>
    <problem-spring-web.version>0.26.2</problem-spring-web.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.zalando</groupId>
      <artifactId>problem-spring-web-starter</artifactId>
      <version>${problem-spring-web.version}</version>
      <type>pom</type>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Same SpringSecurityExceptionTest.java as before.

The Spring context can't be build.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalStateException: Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.

If I exclude the ProblemSecurityAutoConfiguration and adapt the expected json respone check for the testAccessDenied():

package org.eu.rubensa.springboot.error;

import com.fasterxml.jackson.databind.JsonNode;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.zalando.problem.spring.web.autoconfigure.security.ProblemSecurityAutoConfiguration;

/**
 * The {@link org.springframework.boot.test.context.SpringBootTest} annotation
 * will load the fully ApplicationContext. This will not use slicing and scan
 * for all the stereotype annotations
 * ({@link org.springframework.stereotype.Component},
 * {@link org.springframework.stereotype.Service},
 * {@link org.springframework.stereotype.Repository} and
 * {@link org.springframework.stereotype.Controller} /
 * {@link org.springframework.web.bind.annotation.RestController}) and loads the
 * full application context.
 */
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
    /**
     * When you add the Security starter without custom security configurations,
     * Spring Boot endpoints will be secured using HTTP basic authentication with a
     * default user and generated password. To override that, you can configure
     * credentials in application.properties as follows
     */
    "spring.security.user.name=username", "spring.security.user.password=password" })
public class SpringSecurityExceptionTest {
  private static final String USER_NAME = "username";
  private static final String USER_PASSWORD = "password";

  @Autowired
  private TestRestTemplate testRestTemplate;

  @Test
  public void testAccessOK() throws Exception {
    final ResponseEntity<String> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/access-ok", HttpMethod.GET, null, String.class);
    Assertions.assertThat(response.getBody()).isEqualTo("OK");
  }

  @Test
  public void testAccessDenied() throws Exception {
    final ResponseEntity<JsonNode> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/deny-all", HttpMethod.GET, null, JsonNode.class);
    Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
    JsonNode jsonResponse = response.getBody();
    Assertions.assertThat(jsonResponse.findValue("status").asInt()).isEqualTo(403);
    Assertions.assertThat(jsonResponse.findValue("title").asText()).isEqualTo("Forbidden");
  }

  /**
   * A single {@link org.springframework.boot.autoconfigure.SpringBootApplication}
   * annotation can be used to enable:
   * <ul>
   * <li>{@link org.springframework.boot.autoconfigure.EnableAutoConfiguration}:
   * enable Spring Boot’s auto-configuration mechanism</li>
   * <li>{@link org.springframework.context.annotation.ComponentScan}: enable
   * {@link org.springframework.stereotype.Component} scan on the package where
   * the application is located (see the best practices)</li>
   * <li>{@link org.springframework.context.annotation.Configuration}: allow to
   * register extra beans in the context or import additional configuration
   * classes</li>
   * </ul>
   * <p>
   * A nested {@link org.springframework.context.annotation.Configuration} class
   * wild be used instead of the application’s primary configuration.
   * <p>
   * Unlike a nested {@link org.springframework.context.annotation.Configuration}
   * class, which would be used instead of your application’s primary
   * configuration, a nested
   * {@link org.springframework.boot.test.context.TestConfiguration} class is used
   * in addition to your application’s primary configuration.
   */
  @Configuration
  /**
   * Tells Spring Boot to start adding beans based on classpath settings, other
   * beans, and various property settings.
   * <p>
   * Eclude {@link ProblemSecurityAutoConfiguration}. see:
   * https://github.com/zalando/problem-spring-web/issues/573
   */
  @EnableAutoConfiguration(exclude = ProblemSecurityAutoConfiguration.class)
  /**
   * Provides AOP security on methods. Some of the annotations that it provides
   * are PreAuthorize, PostAuthoriz
   */
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  /**
   * The {@link org.springframework.context.annotation.ComponentScan} tells Spring
   * to look for other components, configurations, and services in the the
   * TestConfig package.
   * <p>
   * We only want to test the classes defined inside this test configuration so we
   * do nos use it here.
   */
  static class TestConfig {
    @RestController
    public static class TestController {
      @GetMapping("/access-ok")
      public @ResponseBody String getAccessOk() {
        return "OK";
      }

      @GetMapping("/deny-all")
      @PreAuthorize("denyAll()")
      public void getAccessDenied() {
      }
    }
  }
}

The testAccessDenied() do not pass as an error 500 is issued (instead of the expected 403).

[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 5.272 s <<< FAILURE! - in org.eu.rubensa.springboot.error.SpringSecurityExceptionTest
[ERROR] testAccessDenied  Time elapsed: 1.019 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 

Expecting:
 <500 INTERNAL_SERVER_ERROR>
to be equal to:
 <403 FORBIDDEN>
but was not.
        at org.eu.rubensa.springboot.error.SpringSecurityExceptionTest.testAccessDenied(SpringSecurityExceptionTest.java:60)

2021-05-11 13:33:58.190  INFO 18631 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

@rubensa
Copy link

rubensa commented May 11, 2021

This is how I managed to get a working test but I had to manually configure the Problem Security support (so I don't like the solution at all):
SpringSecurityExceptionTest.java

package org.eu.rubensa.springboot.error;

import com.fasterxml.jackson.databind.JsonNode;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
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.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.zalando.problem.spring.web.advice.AdviceTrait;
import org.zalando.problem.spring.web.advice.ProblemHandling;
import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
import org.zalando.problem.spring.web.autoconfigure.security.ProblemSecurityAutoConfiguration;

/**
 * The {@link org.springframework.boot.test.context.SpringBootTest} annotation
 * will load the fully ApplicationContext. This will not use slicing and scan
 * for all the stereotype annotations
 * ({@link org.springframework.stereotype.Component},
 * {@link org.springframework.stereotype.Service},
 * {@link org.springframework.stereotype.Repository} and
 * {@link org.springframework.stereotype.Controller} /
 * {@link org.springframework.web.bind.annotation.RestController}) and loads the
 * full application context.
 */
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
    /**
     * When you add the Security starter without custom security configurations,
     * Spring Boot endpoints will be secured using HTTP basic authentication with a
     * default user and generated password. To override that, you can configure
     * credentials in application.properties as follows
     */
    "spring.security.user.name=username", "spring.security.user.password=password" })
public class SpringSecurityExceptionTest {
  private static final String USER_NAME = "username";
  private static final String USER_PASSWORD = "password";

  @Autowired
  private TestRestTemplate testRestTemplate;

  @Test
  public void testAccessOK() throws Exception {
    final ResponseEntity<String> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/access-ok", HttpMethod.GET, null, String.class);
    Assertions.assertThat(response.getBody()).isEqualTo("OK");
  }

  @Test
  public void testAccessDenied() throws Exception {
    final ResponseEntity<JsonNode> response = testRestTemplate.withBasicAuth(USER_NAME, USER_PASSWORD)
        .exchange("/deny-all", HttpMethod.GET, null, JsonNode.class);
    Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
    JsonNode jsonResponse = response.getBody();
    Assertions.assertThat(jsonResponse.findValue("status").asInt()).isEqualTo(403);
    Assertions.assertThat(jsonResponse.findValue("title").asText()).isEqualTo("Forbidden");
  }

  /**
   * A single {@link org.springframework.boot.autoconfigure.SpringBootApplication}
   * annotation can be used to enable:
   * <ul>
   * <li>{@link org.springframework.boot.autoconfigure.EnableAutoConfiguration}:
   * enable Spring Boot’s auto-configuration mechanism</li>
   * <li>{@link org.springframework.context.annotation.ComponentScan}: enable
   * {@link org.springframework.stereotype.Component} scan on the package where
   * the application is located (see the best practices)</li>
   * <li>{@link org.springframework.context.annotation.Configuration}: allow to
   * register extra beans in the context or import additional configuration
   * classes</li>
   * </ul>
   * <p>
   * A nested {@link org.springframework.context.annotation.Configuration} class
   * wild be used instead of the application’s primary configuration.
   * <p>
   * Unlike a nested {@link org.springframework.context.annotation.Configuration}
   * class, which would be used instead of your application’s primary
   * configuration, a nested
   * {@link org.springframework.boot.test.context.TestConfiguration} class is used
   * in addition to your application’s primary configuration.
   */
  @Configuration
  /**
   * Tells Spring Boot to start adding beans based on classpath settings, other
   * beans, and various property settings.
   * <p>
   * Exclude {@link ProblemSecurityAutoConfiguration}. see:
   * https://github.com/zalando/problem-spring-web/issues/573
   */
  @EnableAutoConfiguration(exclude = ProblemSecurityAutoConfiguration.class)
  /**
   * Provides AOP security on methods. Some of the annotations that it provides
   * are PreAuthorize, PostAuthoriz
   */
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  /**
   * The {@link org.springframework.context.annotation.ComponentScan} tells Spring
   * to look for other components, configurations, and services in the the
   * TestConfig package.
   * <p>
   * We only want to test the classes defined inside this test configuration so we
   * do nos use it here.
   */
  static class TestConfig {
    @Configuration
    @Import(SecurityProblemSupport.class)
    public class ProblemSecurityConfiguration extends WebSecurityConfigurerAdapter {
      private final SecurityProblemSupport support;

      public ProblemSecurityConfiguration(SecurityProblemSupport support) {
        this.support = support;
      }

      @Override
      public void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic().and()
            .exceptionHandling().authenticationEntryPoint(support).accessDeniedHandler(support);
      }

      @Bean
      public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher) {
        return new DefaultAuthenticationEventPublisher(publisher);
      }

      @Bean
      @ConditionalOnMissingBean(AdviceTrait.class)
      public AdviceTrait securityExceptionHandling() {
        return new SecurityExceptionHandling();
      }
    }

    @ControllerAdvice
    final class SecurityExceptionHandling implements ProblemHandling, SecurityAdviceTrait {
    }

    @RestController
    public static class TestController {
      @GetMapping("/access-ok")
      public @ResponseBody String getAccessOk() {
        return "OK";
      }

      @GetMapping("/deny-all")
      @PreAuthorize("denyAll()")
      public void getAccessDenied() {
      }
    }
  }
}

@IncPlusPlus
Copy link

Has there been any progress with this? I'm running into the same issue and I haven't found a simple fix yet.

@aafwu00
Copy link
Contributor

aafwu00 commented Aug 30, 2021

@whiskeysierra I think this issue fixed by #674

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants