unit-test-security-authorization — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited unit-test-security-authorization (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill provides patterns for unit testing Spring Security authorization logic using @PreAuthorize, @Secured, @RolesAllowed, and custom permission evaluators. It covers testing role-based access control (RBAC), expression-based authorization, custom permission evaluators, and verifying access denied scenarios without full Spring Security context.
Use this skill when:
@PreAuthorize and @Secured method-level securityFollow these steps to test Spring Security authorization:
Add spring-security-test to your test dependencies:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>@Configuration
@EnableMethodSecurity
class TestSecurityConfig { }@WithMockUser@Test
@WithMockUser(roles = "ADMIN")
void shouldAllowAdminAccess() {
assertThatCode(() -> service.deleteUser(1L))
.doesNotThrowAnyException();
}
@Test
@WithMockUser(roles = "USER")
void shouldDenyUserAccess() {
assertThatThrownBy(() -> service.deleteUser(1L))
.isInstanceOf(AccessDeniedException.class);
}@Test
void shouldGrantPermissionToOwner() {
Authentication auth = new UsernamePasswordAuthenticationToken(
"alice", null, List.of(new SimpleGrantedAuthority("ROLE_USER"))
);
Document doc = new Document(1L, "Test", new User("alice"));
boolean result = evaluator.hasPermission(auth, doc, "WRITE");
assertThat(result).isTrue();
}If tests pass unexpectedly, add this assertion to verify security is enforced:
@Test
void shouldRejectUnauthorizedWhenSecurityEnabled() {
assertThatThrownBy(() -> service.deleteUser(1L))
.isInstanceOf(AccessDeniedException.class);
}| Annotation | Description | Example |
|---|---|---|
@PreAuthorize | Pre-invocation authorization | @PreAuthorize("hasRole('ADMIN')") |
@PostAuthorize | Post-invocation authorization | @PostAuthorize("returnObject.owner == authentication.name") |
@Secured | Simple role-based security | @Secured("ROLE_ADMIN") |
@RolesAllowed | JSR-250 standard | @RolesAllowed({"ADMIN", "MANAGER"}) |
@WithMockUser | Test annotation | @WithMockUser(roles = "ADMIN") |
@PreAuthorize Test@Service
public class UserService {
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long userId) {
// delete logic
}
}
// Test
@Test
@WithMockUser(roles = "ADMIN")
void shouldAllowAdminToDeleteUser() {
assertThatCode(() -> service.deleteUser(1L))
.doesNotThrowAnyException();
}
@Test
@WithMockUser(roles = "USER")
void shouldDenyUserFromDeletingUser() {
assertThatThrownBy(() -> service.deleteUser(1L))
.isInstanceOf(AccessDeniedException.class);
}@PreAuthorize("#userId == authentication.principal.id")
public UserProfile getUserProfile(Long userId) {
// get profile
}
// For custom principal properties, use @WithUserDetails with a custom UserDetailsService
@Test
@WithUserDetails("alice")
void shouldAllowUserToAccessOwnProfile() {
assertThatCode(() -> service.getUserProfile(1L))
.doesNotThrowAnyException();
}Validation tip: If a security test passes unexpectedly, verify that@EnableMethodSecurityis active on the test configuration — a missing annotation causes all@PreAuthorizechecks to be bypassed silently.
See references/basic-testing.md for more basic patterns and references/advanced-authorization.md for complex expressions and custom evaluators.
@PreAuthorize works via proxies; direct method calls bypass security@PreAuthorize, @Secured to workhasRole('ADMIN') not hasRole('ROLE_ADMIN')@PreAuthorize can be difficult to debug; test thoroughly@PreAuthorize, @Secured, MockMvc testing, and parameterized tests~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.