0% found this document useful (0 votes)
1 views7 pages

API Secure Design Practices

The document outlines secure design practices for APIs using Spring Boot, including authentication via Keycloak with OAuth2 and JWT, rate limiting with Bucket4j and Redis, API key management, audit logging with ELK and AOP, and access control using Keycloak RBAC. It provides implementation steps, necessary dependencies, and code snippets for each practice. The focus is on ensuring security and proper access management in API development.

Uploaded by

ap998970
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views7 pages

API Secure Design Practices

The document outlines secure design practices for APIs using Spring Boot, including authentication via Keycloak with OAuth2 and JWT, rate limiting with Bucket4j and Redis, API key management, audit logging with ELK and AOP, and access control using Keycloak RBAC. It provides implementation steps, necessary dependencies, and code snippets for each practice. The focus is on ensuring security and proper access management in API development.

Uploaded by

ap998970
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

🔐 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 application.yml.
4. Protect endpoints using Spring Security + OAuth2 resource server.
5. Decode and validate JWTs.

📜 Dependencies (Maven):

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-
server</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>

⚙️ application.yml

spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/realms/myrealm

🔐 SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt());

return http.build();
}
}

🚦 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>com.github.vladimir-bukhtoyarov</groupId>
<artifactId>bucket4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

📦 RateLimiterFilter.java

@Component
public class RateLimiterFilter extends OncePerRequestFilter {

private final RedisTemplate<String, Bucket> redisTemplate;

public RateLimiterFilter(RedisTemplate<String, Bucket>


redisTemplate) {
this.redisTemplate = redisTemplate;
}

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String ip = request.getRemoteAddr();
Bucket bucket = redisTemplate.opsForValue().get(ip);

if (bucket == null) {
Refill refill = Refill.greedy(60, Duration.ofMinutes(1));
Bandwidth limit = Bandwidth.classic(60, refill);
bucket = Bucket.builder().addLimit(limit).build();
redisTemplate.opsForValue().set(ip, bucket);
}

if (bucket.tryConsume(1)) {
filterChain.doFilter(request, response);
} else {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
response.getWriter().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: ApiKey.java

@Entity
public class ApiKey {
@Id
private String key;
private String owner;
private boolean active;
}

🧩 ApiKeyInterceptor.java

@Component
public class ApiKeyInterceptor implements HandlerInterceptor {
@Autowired private ApiKeyRepository apiKeyRepository;

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws IOException {
String apiKey = request.getHeader("X-API-KEY");
if (apiKey == null
|| !apiKeyRepository.existsByIdAndActiveTrue(apiKey)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write("Invalid API Key");
return false;
}
return true;
}
}

🧬 WebConfig.java

@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired ApiKeyInterceptor apiKeyInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(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.

🧠 AuditAspect.java

@Aspect
@Component
public class AuditAspect {
private static final Logger logger =
LoggerFactory.getLogger("AUDIT");

@Before("execution(* com.example..*.*(..))")
public void logBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.currentRequestAttributes()).getRequest();
logger.info("API called: {} by IP: {}",
joinPoint.getSignature(), request.getRemoteAddr());
}
}

🧠 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.

🔐 application.yml

spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/realms/myrealm
🔍 Example Controller

@RestController
@RequestMapping("/employee")
public class EmployeeController {

@PreAuthorize("hasAuthority('SCOPE_read')")
@GetMapping("/me")
public ResponseEntity<?> getMyProfile() {
return ResponseEntity.ok("Your profile");
}

@PreAuthorize("hasAuthority('SCOPE_admin')")
@GetMapping("/all")
public ResponseEntity<?> getAllProfiles() {
return ResponseEntity.ok("All profiles");
}
}

You might also like