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
2
Answers
Add this configuration to test class :
@EnableGlobalMethodSecurity(prePostEnabled = true)
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):
@WithMockUser
populates test security context withUsernamePasswordAuthenticationToken
which is not adapted to OAuth2 resource-servers.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.
Stop trying to build JWTs to set it as request header when working with MockMvc. Use either
org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt
fromspring-security-test
or@WithMockJwtAuth
fromspring-addons-oauth2-test
.