Spring Boot Authentication for Integration Tests
Solution 1
You can try excluding few more auto configurations:
@EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration.class
})
Btw, more elegant way of excluding stuff is by defining application-test.properties
in your test sources and marking your test with @Profile("test")
. Then just add this to your config:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration
All the possible configurations that can be excluded you can find here: spring.factories
Solution 2
You have couple of options to provide authentication in the spring boot integration test. You may need to adjust a few things to make it all work at your end.
Mock based approach
This uses test WebApplicationContext
injected into MockMvc with @WithMockUser annotation to provide authentication user and WithMockUserSecurityContextFactory
creating the security context for the mock user.
SecurityMockMvcConfigurers
registers the security filter springSecurityFilterChain
with MockMvc
.
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class HelloControllerIT {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity()) // enable security for the mock set up
.build();
}
@WithMockUser(value = "test", password = "pass")
@Test
public void test() throws Exception {
String contentType = MediaType.APPLICATION_JSON + ";charset=UTF-8";
String authzToken = mvc
.perform(
post("/authenticate")
.contentType(
MediaType.APPLICATION_JSON).
content("")).
andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.token", is(notNullValue())))
.andReturn().getResponse().getContentAsString();
System.out.print(authzToken);//{"token":"1a3434a"}
}
}
In-memory auth provider based approach
This uses in-memory auth provider with basic authentication user.
Register in-memory auth provider and enable basic auth, disable anonymous access in HttpSecurity
in the WebSecurityConfigurerAdapter
.
When in-memory provider is registered, DefaultInMemoryUserDetailsManagerConfigurer
creates the basic auth user in the memory.
When basic authentication is enabled, HttpBasicConfigurer
configures BasicAuthenticationFilter
. Authenticates the test user and creates the security context.
Security Configuration
@EnableWebSecurity
@EnableWebMvc
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// register test user with in memory authentication provider
auth.inMemoryAuthentication().withUser("test").password("pass").roles("ROLES");
}
@Override
public void configure(HttpSecurity http) throws Exception {
// enable basic authentication & disable anoymous access
http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and().anonymous().disable();
}
}
Authentication Endpoint
@Controller
@RequestMapping("/authenticate")
public class AuthenticationController {
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public TokenClass getToken() {
TokenClass tokenClass = new TokenClass();
tokenClass.setToken("1a3434a");
return tokenClass;
}
}
Pojo
public class TokenClass {
private String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
Test Controller
import com.fasterxml.jackson.databind.JsonNode;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.Base64;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {
@Autowired
private TestRestTemplate template;
@Test
public void test() throws Exception {
HttpHeaders authHeaders = new HttpHeaders();
String token = new String(Base64.getEncoder().encode(
("test" + ":" + "pass").getBytes()));
authHeaders.set("Authorization", "Basic " + token);
JsonNode loginResponse = template.postForObject("/authenticate", new HttpEntity<>(null, authHeaders), JsonNode.class);
HttpHeaders authzHeaders = new HttpHeaders();
authzHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
authzHeaders.add("X-Authorization", "Bearer " + loginResponse.get("token").textValue());
authzHeaders.add("Content-Type", "application/json");
ResponseEntity response = template.exchange("/secure",
HttpMethod.GET,
new HttpEntity<>(null, authzHeaders),
String.class
);
}
}
Solution 3
It looks like default security configuration are getting kicked-in. Unless I see your your complete configuration it is hard to confirm this. If possible, could you post the your minimal project (on github?).
Since you do not want to enforce the authentication during executions of integration tests, you may enable the anonymous access of your application resources.
To enable anonymous access, you may add below class under your test source directory. It will configure the anonymous access during bootstrapping the web application. (should not see 401 response code)
@Configuration
public class AllowAnonymousWebAccess extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity web) throws Exception {
web.antMatcher("**/*").anonymous();
}
}
Solution 4
Was facing this issue for a long time. Finally got it resolved. You need to mock the Authorization server creating a test profile and will also need to Mock Spring Security user details service. Here is the code that I found in a blog.
Test Authorization server
@Configuration
@EnableAuthorizationServer
@ActiveProfiles("test")
public class AuthorizationTestServer extends AuthorizationServerConfigurerAdapter {
private AuthenticationManager authenticationManager;
@Autowired
public AuthorizationTestServer(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess("permitAll()");
oauthServer.allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
super.configure(clients);
clients.inMemory()
.withClient("user")
.secret("password")
.authorizedGrantTypes("password")
.scopes("openid");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
super.configure(endpoints);
endpoints.authenticationManager(this.authenticationManager);
}
}
Test User Details Service
@Service
@ActiveProfiles("test")
public class UserDetailTestService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return new User("dummyUser","dummyPassword",true,true,
true,true, AuthorityUtils.createAuthorityList("USER"));
}
}
Main Test class
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@AutoConfigureMockMvc
public class JmStudentServiceApplicationTests {
@Autowired
private WebApplicationContext wac;
@Autowired
private MockMvc mockMvc;
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private StudentRepository studentRepository;
@Test
public void test() throws Exception{
String accessToken = obtainAccessToken("dummyUser", "dummyPassword");
Student student = new Student();
student.setId("2222");
student.setName("test student");
studentRepository.createStudent(student);
assertTrue(studentRepository.getStudentById("2222").getName().equals("test student"));
MvcResult result = mockMvc.perform(get("/students/by-id/2222")
.header("Authorization", "Bearer " + accessToken)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
String str = result.getResponse().getContentAsString();
assertTrue(str.contains("\"id\":\"2222\""));
}
private String obtainAccessToken(String username, String password) throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "password");
params.add("username", username);
params.add("password", password);
params.add("scope", "openid");
String base64ClientCredentials = new String(Base64.encodeBase64("user:password".getBytes()));
ResultActions result
= mockMvc.perform(post("/oauth/token")
.params(params)
.header("Authorization","Basic " + base64ClientCredentials)
.accept("application/json;charset=UTF-8"))
.andExpect(status().isOk());
String resultString = result.andReturn().getResponse().getContentAsString();
JacksonJsonParser jsonParser = new JacksonJsonParser();
return jsonParser.parseMap(resultString).get("access_token").toString();
}
}
Solution 5
For bypassing basic authentication while testing With @SpringBootTest and TestRestTemplate, we can chain .withBasicAuth("admin", "password") to template, see below
@Test
public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
ResponseEntity<String> result = template.withBasicAuth("spring", "secret")
.getForEntity("/private/hello", String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
}
for more info see https://www.baeldung.com/spring-security-integration-tests
Richard
Updated on July 27, 2020Comments
-
Richard almost 4 years
I'm trying to run an integration test for my controller but I am running into issues if I don't authenticate. Here's my controller:
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"security.basic.enabled=false", "management.security.enabled=false"}) @EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class}) public class HelloControllerIT { private final ObjectMapper mapper = new ObjectMapper(); @Autowired private TestRestTemplate template; @Test public void test1() throws Exception { ObjectNode loginRequest = mapper.createObjectNode(); loginRequest.put("username","name"); loginRequest.put("password","password"); JsonNode loginResponse = template.postForObject("/authenticate", loginRequest.toString(), JsonNode.class); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.add("X-Authorization", "Bearer " + loginResponse.get("token").textValue()); headers.add("Content-Type", "application/json"); return new HttpEntity<>(null, headers); HttpEntity request = getRequestEntity(); ResponseEntity response = template.exchange("/get", HttpMethod.GET, request, new ParameterizedTypeReference<List<Foo>>() {}); //assert stuff } }
When I run this, everything works. But if I comment out the line:
headers.add("X-Authorization", "Bearer " + loginResponse.get("token").textValue());
I get the error:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: java.io.PushbackInputStream@272a5bc6; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: java.io.PushbackInputStream@272a5bc6; line: 1, column: 1] at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:234) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:219) at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95) at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:917) at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:901) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:655) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613) at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:559) at org.springframework.boot.test.web.client.TestRestTemplate.exchange(TestRestTemplate.java:812) at com.test.HelloControllerIT.test1(HelloControllerIT.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: java.io.PushbackInputStream@272a5bc6; line: 1, column: 1] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234) at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122) at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:338) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:269) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2922) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:231) ... 38 more
Obviously the security annotations at the top are not working. So what exactly is the issue and how do I fix it?
Edit 1: I tried doing:
Object response = template.exchange("/get", HttpMethod.GET, request, Object.class);
And got:
<401 Unauthorized,{status=401, message=Authentication failed, errorCode=10, timestamp=1497654855545},{X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Content-Type=[application/json;charset=ISO-8859-1], Content-Length=[89], Date=[Fri, 16 Jun 2017 23:14:15 GMT]}>
For our security we're using
org.springframework.security.authentication.AuthenticationProvider
andorg.springframework.security.authentication.AuthenticationManager
Edit 2: Per skadya's suggestion I created a new class like so:
@Configuration public class AnonymousConfig extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity web) throws Exception { web.antMatcher("**/*").anonymous(); } }
But now when I run my integration test I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:47) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. Order of 100 was already used on config.AnonymousConfig$$EnhancerBySpringCGLIB$$ba18b8d7@6291f725, so it cannot be used on security.WebSecurityConfig$$EnhancerBySpringCGLIB$$9d88e7e@1bfaaae1 too. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ... 23 more Caused by: java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. Order of 100 was already used on config.AnonymousConfig$$EnhancerBySpringCGLIB$$ba18b8d7@6291f725, so it cannot be used on security.WebSecurityConfig$$EnhancerBySpringCGLIB$$9d88e7e@1bfaaae1 too. at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(WebSecurityConfiguration.java:148) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:701) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ... 40 more
Looks like it's clashing with the websecurity config we have in the normal project. Here's that file:
@EnableWebSecurity @EnableWebMvc @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { //configuration }
I tried adding
@Order(1000)
which fixed the above issue but still ended up in a401 Unauthorized