Annotaion:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.METHOD})
public @interface HasRole {
String[] value();
}
Aspect:
@Aspect
@Component
public class SecurityAspect {
private final Logger logger = LoggerFactory.getLogger(SecurityAspect.class);
private final JwtUtil jwtUtil;
private final UserRepo userRepo;
public SecurityAspect(JwtUtil jwtUtil, UserRepo userRepo) {
this.jwtUtil = jwtUtil;
this.userRepo = userRepo;
}
@Pointcut("@annotation(hasRole)")
public void hasRoleAnnotation(HasRole hasRole) {}
@Before("hasRoleAnnotation(hasRole)")
public void hasRole(HasRole hasRole) {
HttpServletRequest request =
((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String authorizationHeader = request.getHeader(Constants.AUTHORIZATION_HEADER);
if (authorizationHeader == null || !authorizationHeader.startsWith(Constants.TOKEN_PREFIX)) {
throw new ForbiddenException("Unauthorized", "Authentication token is required");
}
String token = authorizationHeader.replace(Constants.TOKEN_PREFIX, "");
logger.info("Token : {}", token);
Claims claims = jwtUtil.validateAndExtractClaims(token);
Integer userId = claims.get(Constants.SUBJECT, Integer.class);
UserDto userDto = new UserDto().get(userRepo.findById(userId));
List<String> roles = userDto.getRoles().stream().map(RoleDto::getName).collect(Collectors.toList());
if(!roles.containsAll(Arrays.stream(hasRole.value()).collect(Collectors.toList()))){
throw new ForbiddenException("Unauthorized", "you are not " + Arrays.toString(hasRole.value()));
}
}
}
Controller:
@RestController
public class AuthenticationController {
@HasRole("ADMIN")
@GetMapping
public String getInit() {
Integer userId = SecurityUtils.getCurrentUserUserId()
.orElseThrow(() -> new ForbiddenException("Unauthorized", "Authentication token is required"));
return "WELCOME " + userId;
}
}
The output for the request is "WELCOME 1"
@HasRole("ADMIN")
@RestController
public class AuthenticationController {
@GetMapping
public String getInit() {
Integer userId = SecurityUtils.getCurrentUserUserId()
.orElseThrow(() -> new ForbiddenException("Unauthorized", "Authentication token is required"));
return "WELCOME " + userId;
}
}
but for the class annotation it is throwing the error How to solve it? And how do I determine the order of execution of the annotations if more than one annotation is specified on a single class or method