使用@PreAuthorize测试Spring MVC控制器,拒绝403-Access

时间:2017-03-28 15:20:17

标签: java spring spring-mvc spring-security spock

尝试使用Spock框架为我的控制器编写一些集成测试,该控制器上有@PreAuthorize注释。当我运行应用程序时,这个标签就像一个魅力。但是,当我运行集成测试时,我得到403。

我的SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers("/test/**")
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .csrf().disable(); 
      }
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() {
        return new   ProviderManager(Arrays.asList(getAuthenticationProvider()));
    }

}

我的控制器:

@RestController
@Validated
@RequestMapping("/test")
public class TestController  {


    @PreAuthorize("hasPermission(#object, '')")
    @RequestMapping(method = RequestMethod.POST,
                    consumes = MediaType.APPLICATION_JSON_VALUE,
                    produces = MediaType.APPLICATION_JSON_VALUE,
                    headers = { "Accept=application/json", "Content-Type=application/json" })
    public ResponseEntity<List<String>> testController(@RequestBody @Valid TestObject object,
            @RequestHeader(ACCOUNT) String account)
            throws ResourceNotFoundException, ServletRequestBindingException,
            MethodArgumentNotValidException, NoSuchMethodException, SecurityException {
//return statement here!!
        }
}

和我的PermissionEvaluator如下:

@Component
public class TestPermissionEvaluator implements PermissionEvaluator {

        private HttpServletRequest request;
        private TestRepository<AccountRoles> repository;

@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object
                    permission) {
            AccountRole accountRole;
            TestObject object = (TestObject) targetDomainObject;
                try {
                    accountRole = repository.find(object.getAccountID(), id);
                } catch (ResourceNotFoundException e) {
        //      throw new Exception here
                }

                return true;
            }

            @Override
            public boolean hasPermission(Authentication authentication, Serializable targetId, String
                    targetType, Object permission) {
                return false;
            }
        }

最后我的测试类看起来如下:

@ContextConfiguration(locations = ['file:src/main/webapp/WEB-INF/spring/testWebmvc-config.xml',
    'file:src/main/webapp/WEB-INF/spring/appContext/servlet-context.xml'])
@WebAppConfiguration
public class TestControllerIntegration extends Specification {

    TestController controller
    MockMvc mockMvc

    @Inject
    WebApplicationContext wac


    @Inject
    ObjectMapper mapper

    @Autowired
    private FilterChainProxy filterChainProxy

    def setup() {
        controller = new TestController()
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(filterChainProxy).apply(SecurityMockMvcConfigurers.springSecurity()).build()
        SecurityContextHolder.clearContext()
        SecurityContextHolder.getContext().setAuthentication(new TestAuthenticationToken("145214741"))
    }

    @Unroll
    def 'valid post to /test'() {

        when:
        MvcResult result = mockMvc.perform(post('/test').
            content(readJsonFromFile(jsonFileLocation)).
            contentType(APPLICATION_JSON).
            header('account', account).
            accept(APPLICATION_JSON)).
            andDo(print()).
            andReturn()
        then:
        def ids = mapper.readValue(result.response.getContentAsString(), List.class)

    }

每当我尝试运行此测试时,我会得到一个带有以下堆栈跟踪的403:

MockHttpServletResponse:
           Status = 403
    Error message = Access Denied
          Headers = {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 = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: ; line: 1, column: 1]

我在这里错过了什么,先谢谢!!

0 个答案:

没有答案