4

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.

piotras256
  • 51
  • 3
  • When I create new test class, that starst with full Spring auto-configuration (@SpringBootTest instead of @SpringMvcTest), and create mockMvc manually the test method works correctly. – piotras256 Jul 23 '19 at 15:31
  • I also tried to create UserSecurity bean with Configuration and Bean instead of Component (@WebMvcTest is not supposed to handle Component beans), it didn't change anything. – piotras256 Jul 23 '19 at 15:36

0 Answers0