Shared library for the Library Booking System: AOP aspects, security components, and exceptions for microservices.
From the workspace root directory:
# Build everything (common-aspects + all services)
.\build-all.ps1
# Start services
cd docker-compose
docker-compose up -dLoggingAspect- Automatic method logging with execution time
JwtUtil- JWT token validation and claim extractionBaseJwtAuthenticationFilter- Base filter for JWT authentication (extend per service)BaseAuthorizationAspect- Role and ownership authorization checks
@RequiresRole- Declarative role-based access control@RequiresOwnership- Resource ownership validation
ForbiddenException- Access denied exceptionGlobalExceptionHandler- Base exception handler (extend per service)
com.library.common
├── aspect
│ └── LoggingAspect.java
├── exception
│ ├── ForbiddenException.java
│ └── GlobalExceptionHandler.java
└── security
├── JwtUtil.java
├── BaseJwtAuthenticationFilter.java
├── annotation
│ ├── RequiresRole.java
│ └── RequiresOwnership.java
└── aspect
└── BaseAuthorizationAspect.java
All services have been migrated to use common-aspects:
- user-service
- auth-service
- booking-service (+ custom @RequiresBookingOwnership)
- catalog-service
- policy-service
- notification-service (+ custom @RequiresNotificationOwnership)
- analytics-service
@Component
public class JwtAuthenticationFilter extends BaseJwtAuthenticationFilter {
@Override
protected Set<String> getPublicEndpoints() {
return Set.of("/api/health", "/api/your-service/public");
}
}@GetMapping
@RequiresRole // Any authenticated user
public List<Resource> getAll() { ... }
@PostMapping
@RequiresRole({"ADMIN"}) // Admin only
public Resource create(@RequestBody Resource r) { ... }
@GetMapping("/{id}")
@RequiresRole
@RequiresOwnership(resourceIdParam = "id") // Owner or admin
public Resource getById(@PathVariable Long id) { ... }@RestControllerAdvice
public class ServiceExceptionHandler extends GlobalExceptionHandler {
@ExceptionHandler(YourCustomException.class)
public ResponseEntity<?> handleCustomException(YourCustomException e) {
// Handle service-specific exceptions
}
}