我只是想在订单控制器的方法中添加一个@PreAuthorize("hasAuthority('ROLE_ADMIN')")
和@PreAuthorize("hasAuthority('ROLE_USER')")
,并且在auth服务中定义了User和Admin角色的登录方法后,我还修改了控制器的测试方法。
我添加控制器的placeOrder方法的@PreAuthorize("hasAuthority('ROLE_USER')")
后,修改了它的测试方法。
这里是顺序控制器的方法
@PreAuthorize("hasAuthority('ROLE_USER')")
@PostMapping("/placeorder")
public ResponseEntity<Long> placeOrder(@RequestBody OrderRequest orderRequest) {
log.info("OrderController | placeOrder is called");
log.info("OrderController | placeOrder | orderRequest: {}", orderRequest.toString());
long orderId = orderService.placeOrder(orderRequest);
log.info("Order Id: {}", orderId);
return new ResponseEntity<>(orderId, HttpStatus.OK);
}
下面是订单服务中ordercontrollertest中的测试方法示例。
@Test
@DisplayName("Place Order -- Success Scenario")
void test_When_placeOrder_DoPayment_Success() throws Exception {
OrderRequest orderRequest = getMockOrderRequest();
String jwt = getJWTTokenForRoleUser();
MvcResult mvcResult
= mockMvc.perform(MockMvcRequestBuilders.post("/order/placeorder")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.header("Authorization", "Bearer " + jwt)
.content(objectMapper.writeValueAsString(orderRequest)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
String orderId = mvcResult.getResponse().getContentAsString();
Optional<Order> order = orderRepository.findById(Long.valueOf(orderId));
assertTrue(order.isPresent());
Order o = order.get();
assertEquals(Long.parseLong(orderId), o.getId());
assertEquals("PLACED", o.getOrderStatus());
assertEquals(orderRequest.getTotalAmount(), o.getAmount());
assertEquals(orderRequest.getQuantity(), o.getQuantity());
}
以下是订单服务的依赖项。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
如何在这个测试方法中定义ROLE ?我试图使用@WithMockUser(roles="USER")
和@WithMockUser(roles="ADMIN")
,但它没有帮助我。(I got 403 Forbidden error.)
编辑(我也试图在服务WebSecurityConfig,但它没有帮助我解决这个问题。这就是为什么我把它从服务中删除。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(
authorizeRequest -> authorizeRequest
.anyRequest()
.authenticated());
return http.build();
}
}
示例链接:link
下面是测试控制器:Link要运行应用程序,1)运行Service registry (Eureka Server)
2)运行config server3)通过以下命令在docker上运行zipkin和redisDocker执行命令-d -p 9411:9411 openzipkin/zipkinDocker运行-d——name redis -p 6379:6379 redis
4)运行api gateway 5)运行其他服务我可能看起来很粗鲁,但我很累给你解决你的问题(这已经是第三次了,如果你第一次尝试的话,我们都会节省很多时间)
遵循这些教程:https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials
它会教你如何(你显然不知道如何正确地做):
- 配置OAuth2资源服务器
- 安全Spring @Components (@Controllers,但也包括@Service和@Repository)
- 为那些具有模拟标识的组件编写单元测试
- 为每个具有模拟身份的微服务编写集成测试
@WithMockUser
使用不适合OAuth2资源服务器的UsernamePasswordAuthenticationToken
填充测试安全上下文。
只需遵循前3个教程(真正的:编写代码并运行测试),然后参考最适合您特定用例的示例。它应该花你不到一个小时。
在使用MockMvc时,停止尝试构建jwt以将其设置为请求头。使用spring-security-test
中的org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt
或spring-addons-oauth2-test
中的@WithMockJwtAuth
。
将此配置添加到测试类:
@EnableGlobalMethodSecurity(prePostEnabled = true)