我正在Junit测试一个对数据库使用JPA存储库的控制器。我的内存数据库中的H2正常工作,并且我的GET Request映射按预期工作。我的PUT得到403,而我希望得到200。我已经尝试使用带有安全false的AutoConfigureMockMvc进行各种不同的配置,并且还排除了安全性自动配置。
在PUT请求,安全性配置方面是否缺少我的东西,还是需要在令牌周围添加配置?
这是我的Junit测试,当updateTest返回403时,saveTest可以正常工作。
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc(secure = false)
@Import(SecurityConfig.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class DBcontroltest {
@Autowired
DbRequest dbRequest;
@Autowired
ConnectionRequestRepository connectionRequestRepository;
@Autowired
private MockMvc mockMvc;
private String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
private Date date;
private String dateFormatted = "2019-11-26T14:33:13.175+0000";
{
try {
date = simpleDateFormat.parse("2019-11-26T14:33:13.175+0000");
} catch (ParseException e) {
e.printStackTrace();
}
}
@Test
public void saveTest() throws Exception {
ConnectionRequest connectionRequest = new ConnectionRequest((long) 1, "bleep", "market", "dev", "conn1", "fun", "java", "styff", "hello", "whoop", date, "dldl");
connectionRequestRepository.save(connectionRequest);
String body = "{\"connectionId\":1,\"requestor\":\"bleep\",\"market\":\"market\",\"platform\":\"dev\",\"environment\":\"conn1\",\"connectionName\":\"fun\",\"connectionType\":\"java\",\"databaseId\":\"styff\",\"databasePwd\":\"hello\",\"email\":\"whoop\",\"requestDate\":\"" + dateFormatted + "\",\"jobStatus\":\"dldl\"}\n" +
" ";
mockMvc.perform(get("/api/selectDB/{connectionId}" ,1))
.andExpect(content().json(body))
.andExpect(status().isOk());
}
@Test
public void updateTest() throws Exception {
ConnectionRequest connectionRequest = new ConnectionRequest((long) 1, "bleep", "market", "dev", "conn1", "connname", "java", "db", "hello", "email@aol.com", date, "done");
connectionRequestRepository.save(connectionRequest);
String body3 = "{\"requestor\":\"NEWGUY\"}";
MockHttpServletRequestBuilder builder =
MockMvcRequestBuilders.put("/api/updateDB/{connectionId}" ,1)
.contentType("application/json")
.content(body3);
System.out.println(connectionRequestRepository.findById((long) 1));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isOk())
.andDo(MockMvcResultHandlers.print());
System.out.println(connectionRequestRepository.findById((long) 1));
}
}
这是我的控制人,
@Data
@RestController
@RequestMapping("/api/")
public class DbRequest {
@Autowired
private ConnectionRequestRepository connectionRequestRepository;
private ConnectionRequest connectionRequest;
@GetMapping("/selectDB/{connectionId}")
public ResponseEntity<ConnectionRequest> getRequestById(@PathVariable("connectionId") Long connectionId) throws Exception {
ConnectionRequest connectionRequest = connectionRequestRepository.findById(connectionId)
.orElseThrow(() -> new Exception("Connection Request " + connectionId + " not found"));
return ResponseEntity.ok().body(connectionRequest);
}
@PutMapping("/updateDB/{connectionId}")
public ResponseEntity<ConnectionRequest> updateConnectionRequest(@PathVariable("connectionId") Long connectionId,
@Valid @RequestBody ConnectionRequest connectionRequestDetails) throws Exception {
long completedDateTime = System.currentTimeMillis();
System.out.println("completeDateTime is " + completedDateTime);
ConnectionRequest connectionRequest = connectionRequestRepository.findById(connectionId)
.orElseThrow(() -> new Exception("Connection Request " + connectionId + " not found"));
System.out.println("value for connectionrequest is " + connectionRequest);
System.out.println("value for connectionrequestdetails is " + connectionRequestDetails);
connectionRequest.setRequestor(connectionRequestDetails.getRequestor());
final ConnectionRequest updatedConnectionRequest = connectionRequestRepository.save(connectionRequest);
return ResponseEntity.ok(updatedConnectionRequest);
}
}
这是运行junit测试的输出,具有良好的数据。我已经测试了该应用程序,并且按预期运行,只有Junit失败。
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /api/updateDB/1
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = {"requestor":"NEWGUY"}
Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@80b6098}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 403
Error message = Forbidden
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 = []
java.lang.AssertionError: Status
Expected :200
Actual :403
<Click to see difference>
答案 0 :(得分:0)
为测试配置文件创建以下内容。
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true)
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root").password("system").roles("SYSTEM");
}
}
在您的测试课中,
public class DBcontroltest {
...
@Test
@WithUserDetails(value = "root")
public void updateTest() throws Exception {
...
}
请在github上访问此项目,我已经使用spring boot使用spring-security设置了spring boot测试。
配置: https://github.com/reflexdemon/shop/blob/master/src/main/java/org/shop/WebSecurityConfig.java
答案 1 :(得分:0)
通过使用csrf,我可以使其正常工作。
MockHttpServletRequestBuilder builder =
put("/api/updateDB/{connectionId}", 1)
.contentType("application/json")
.content(body3)
.contentType(MediaType.APPLICATION_JSON)
.with(csrf());
System.out.println(connectionRequestRepository.findById((long) 1));
this.mockMvc.perform(builder)
.andExpect(content().json(body))
.andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print());
System.out.println(connectionRequestRepository.findById((long) 1));