尝试使用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]
我在这里错过了什么,先谢谢!!