I created a permission for a RPC Operation that requires a certain role. It works so far but I struggle to implement a Spring Boot Test using MockMVC. @MockUser with required role somehow always gets Access Denied
@WithMockUser does not work with A12, because the authorization is not based on Spring roles (ROLE_*). The scope of your RPC operation is checked by the UAA AuthorizationService via the Data Services PermissionEvaluators. This evaluator resolves the scope through the authorization definition (scope → permission → policy → rule) and checks the access rights carried on the principal’s authorities — not the ROLE_* strings that @WithMockUser provides. Therefore access is always denied.
Important: The roles/access rights must be on the principal, not only on the authentication token. Only principal.authorities is considered during authorization (see here).
Hint: If a test is not about authorization at all, you can skip the checks entirely with UAASecurityBypass.runWithSecurityBypass(...).
There are two ways to set up a proper user in your test.
Option 1 — @WithUserDetails
This is also what the Data Services component team uses in its own server integration tests. The principal is loaded by a real UserDetailsService, so its authorities carry the correct role → access-right mapping and the scope is evaluated exactly like in production.
@SpringBootTest
@AutoConfigureMockMvc
class MyRpcOperationIT {
@Autowired
MockMvc mockMvc;
@Test
@WithUserDetails(value = "user-with-my-role",
setupBefore = TestExecutionEvent.TEST_EXECUTION)
void operation_isAllowed_forUserWithRole() throws Exception {
mockMvc.perform(post("/api/v2/rpc")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"jsonrpc":"2.0","id":1,"method":"MY_OPERATION","params":{}}
"""))
.andExpect(status().isOk());
}
}
setupBefore = TEST_EXECUTION is required — the user is set up after the context is ready, just before the test method runs.
Note: Make sure the role is actually mapped — via your authorization definition — to the access right that the policy of the scope checks. If the role exists but is not connected to that access right, the request is denied. This is the most common cause.
Option 2 — Build the principal manually
If you have no UserDetailsService that provides the role, build a UAA-style principal yourself and put it into the security context. The role name and its access rights live on the principal’s GrantedAuthority. Data Services ships UaaTestHelper for this in its dataservices-core test fixtures.
@BeforeEach
void authenticate() {
// authority name = role, plus the access rights the policy checks
var authority = new UaaTestHelper.TestGrantedAuthority(
"MY_ROLE", List.of(new UaaTestHelper.TestAccessRight("MY_ACCESS_RIGHT")));
var user = UaaTestHelper.createUser();
user.setAuthorities(List.of(authority));
UaaTestHelper.setCurrentUserName(user); // -> SecurityContext
}
@AfterEach
void clear() {
SecurityContextHolder.clearContext();
}