【发布时间】:2018-10-07 10:53:00
【问题描述】:
我正在寻找一种如何使用以下设置测试 Spring Boot REST API 的方法:
@RestController
class SomeRestController {
@Autowired
private SomeService someService;
@GetMapping("/getSome")
@PreAuthorize("@canGetSome.isValid()")
public SomeObject getSomeObject() {
return someService.getSomeObject();
}
}
_
@Component
public class CanGetSome{
@Autowired
private final LoggedUser loggedUser;
public boolean isValid() {
return loggedUser.getPermissions().isCanGetSome();
}
}
_
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
...
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().newSession()
.and()
.authorizeRequests())
.anyRequest().authenticated();
}
//custom LoggedUser object which is initzialized on authentication sucessfull
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public LoggedUser loggedUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (LoggedUser) authentication.getPrincipal();
}
...
}
我的测试用例:
@SpringBootTest(
classes = SpringBootApplication,
webEnvironment = RANDOM_PORT)
@ContextConfiguration
class RestSecurityTest extends Specification {
@Autowired
private TestRestTemplate testRestTemplate
@LocalServerPort
private int port
@WithCustomMockUser
def "test testRestTemplare"(){
expect:
def respone = testRestTemplate.getForObject('http://localhost:'+ port+'/getSome', String)
}
_
public class WithCustomMockUserSecurityContextFactory implements WithSecurityContextFactory<WithCustomMockUser> {
@Override
public SecurityContext createSecurityContext(WithCustomMockUser annotation) {
//init securityContext like @WithMockUser but with LoggedUser as principal which return true on loggedUser.getPermissions().isCanGetSome();
}
}
不幸的是,我在测试中得到以下响应:
{
"timestamp": 1524759173851,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/getSome"
}
我还在请求后调试不同的spring过滤器,SecurityContext身份验证为null,后来切换到AnonymousAuthenticationToken
我不知道为什么 SecurityContext 在请求后为空,而不是使用 @WithCustomMockUser 注释初始化的 SecurityContext。任何想法如何解决它?
【问题讨论】:
-
它在您的测试之外工作吗?
-
你试过this吗?我通过了一个类似的问题,这个解决方案(有一些变化)对我有用。试试看,在这里告诉我们结果。 PS.:尝试使用 MockMvc,我无法使用 TestRestTemplate。
标签: java spring spring-security spock spring-test