🔐 API Secure Design Practices 📜
🔐 1. Authentication Gateway Service (Spring Boot +
OAuth2 + JWT + Keycloak)
🔧 Implementation Steps:
1. Set up a Keycloak server and configure a Realm, Client, Roles, and Users.
2. Add Keycloak Spring Boot dependencies.
3. Configure Keycloak properties in [Link].
4. Protect endpoints using Spring Security + OAuth2 resource server.
5. Decode and validate JWTs.
📜 Dependencies (Maven):
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-oauth2-resource-
server</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
⚙️ [Link]
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: [Link]
🔐 [Link]
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> [Link]());
return [Link]();
}
}
🚦 2. Rate Limiting & Throttling (Spring Boot + Bucket4j +
Redis)
🔧 Implementation Steps:
1. Add Bucket4j + Redis dependencies.
2. Configure Redis.
3. Create a filter to apply rate-limiting logic.
📜 Dependencies:
<dependency>
<groupId>[Link]-bukhtoyarov</groupId>
<artifactId>bucket4j-core</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
📦 [Link]
@Component
public class RateLimiterFilter extends OncePerRequestFilter {
private final RedisTemplate<String, Bucket> redisTemplate;
public RateLimiterFilter(RedisTemplate<String, Bucket>
redisTemplate) {
[Link] = redisTemplate;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String ip = [Link]();
Bucket bucket = [Link]().get(ip);
if (bucket == null) {
Refill refill = [Link](60, [Link](1));
Bandwidth limit = [Link](60, refill);
bucket = [Link]().addLimit(limit).build();
[Link]().set(ip, bucket);
}
if ([Link](1)) {
[Link](request, response);
} else {
[Link](HttpStatus.TOO_MANY_REQUESTS.value());
[Link]().write("Too many requests");
}
}
}
🧾 3. API Key Management Service (Spring Boot + DB)
🔧 Implementation Steps:
1. Store API keys in the database.
2. Create a filter/interceptor to extract and verify the API key.
3. Secure all endpoints.
🧱 Entity: [Link]
@Entity
public class ApiKey {
@Id
private String key;
private String owner;
private boolean active;
}
🧩 [Link]
@Component
public class ApiKeyInterceptor implements HandlerInterceptor {
@Autowired private ApiKeyRepository apiKeyRepository;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws IOException {
String apiKey = [Link]("X-API-KEY");
if (apiKey == null
|| ) {
[Link]([Link]());
[Link]().write("Invalid API Key");
return false;
}
return true;
}
}
🧬 [Link]
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired ApiKeyInterceptor apiKeyInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
[Link](apiKeyInterceptor);
}
}
🔍 4. Audit & Logging (Spring Boot + ELK + AOP)
🔧 Implementation Steps:
1. Set up ELK stack.
2. Add Spring AOP for method-level logging.
3. Send logs to Logstash.
🧠 [Link]
@Aspect
@Component
public class AuditAspect {
private static final Logger logger =
[Link]("AUDIT");
@Before("execution(* [Link]..*.*(..))")
public void logBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes)
[Link]()).getRequest();
[Link]("API called: {} by IP: {}",
[Link](), [Link]());
}
}
🧠 5. Access Control & Scope Management (Spring Boot
+ Keycloak RBAC)
🔧 Implementation Steps:
1. Assign roles to users in Keycloak.
2. Map roles/scopes in Spring Boot using @PreAuthorize.
3. Restrict access based on JWT claims.
🔐 [Link]
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: [Link]
🔍 Example Controller
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@PreAuthorize("hasAuthority('SCOPE_read')")
@GetMapping("/me")
public ResponseEntity<?> getMyProfile() {
return [Link]("Your profile");
}
@PreAuthorize("hasAuthority('SCOPE_admin')")
@GetMapping("/all")
public ResponseEntity<?> getAllProfiles() {
return [Link]("All profiles");
}
}