I have simple SpringBoot application that uses Spring Security. Access control works correctly under runtime, but it fails when testing. I get following errors:
java.lang.IllegalArgumentException: Failed to evaluate expression '@userSecurity.hasUserId(authentication,#userId)'
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1058E: A problem occurred when trying to resolve bean 'userSecurity':'Could not resolve bean reference against BeanFactory'
It simply checks if userId provided in Url matches currently logged user via expression
...
.antMatchers("/**/user/{userId}/**/")
.access("@userSecurity.hasUserId(authentication,#userId)")
...
created a bean responsible for User id value check:
@Component
public class UserSecurity {
public boolean hasUserId(Authentication authentication, Long userId) {
Object principalRaw = authentication.getPrincipal();
User loggedUser;
if (principalRaw instanceof User) {
loggedUser = (User) principalRaw;
if (loggedUser.getId() == userId) {
return true;
}
}
return false;
}
}
Finally the test that causes error:
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = StockController.class)
@Import({WebMvcConfig.class, UserSecurity.class})
public class StockControllerTest {
@Autowired
MockMvc mockMvc;
//autowired correctly (Bean exists in Context)
@Autowired
UserSecurity userSecurity;
@Test
@WithMockUser("mockUser")
public void TestControllerSecret() throws Exception {
mockMvc.perform(get("/test/user/1")).andExpect(status().isOk());
}
As You can see I have injected UserSecurity bean just for test purpose, to check if bean exists in Spring Context. I was wondering if @WebMvcTest annotation prevents bean from being created but clearly it doesn't. Bean injects correctly.
Somehow spEL in security access check does not recognize it and throws errors mentioned above.