I just want to add a @PreAuthorize("hasAuthority('ROLE_ADMIN')")
and @PreAuthorize("hasAuthority('ROLE_USER')")
in the methods of order controller and I also revise the controller test method after I define a login method in auth service in terms of User and Admin role.
After I add @PreAuthorize("hasAuthority('ROLE_USER')")
of placeOrder method of controller, I revise its test method.
Here is the method of order controller
@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);
}
Here is the example test method in ordercontrollertest in order service.
@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());
}
Here are the dependenices of order service regarding it.
<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>
How can I define the ROLE in this test method. I tried to use @WithMockUser(roles="USER")
and @WithMockUser(roles="ADMIN")
but it didn't help me. (I got 403 Forbidden error.)
Edited ( I also tried to WebSecurityConfig in the service but it didn't help me fix the issue. That's why I removed it from the service.)
@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();
}
}
Here is the example link : Link
Here is the test controller : Link
To run the app, 1 ) Run Service Registery (Eureka Server)
2 ) Run config server
3 ) Run zipkin and redis through these commands shown below on docker docker run -d -p 9411:9411 openzipkin/zipkin docker run -d --name redis -p 6379:6379 redis
4 ) Run api gateway
5 ) Run other services
CodePudding user response:
Add this configuration to test class :
@EnableGlobalMethodSecurity(prePostEnabled = true)
CodePudding user response:
I might seem rude, but I'm tired to give you the solution to your problem (it's the 3rd time already, and we would have both saved a lot of time if you had tried it the first time)
FOLLOW THOSE TUTORIALS: https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials
It will teach you how to (you obviously don't know how to correctly do it):
- configure your OAuth2 resource-servers
- secure Spring @Components (@Controllers but also @Service and @Repository)
- write unit tests for those components with mocked identities
- write integration test for each micro-service with mocked identities
@WithMockUser
populates test security context with UsernamePasswordAuthenticationToken
which is not adapted to OAuth2 resource-servers.
Stop trying to build JWTs when working with MockMvc
Just follow the first 3 tutoriuals (for real: write the code and run the tests) and then refer to the sample best matching your particular use-case. It should take you less than an hour.