API Security Design Patterns

Rate Limiting Protection

Rate limiting prevants abusive access patterns where malicious actors simulate legitimate users by making excessive requests to APIs. The core concept involves tracking request frequancy and restricting users who exceed defined thresholds.

Implementation Strategy

Time-based restricsions require temporary data storage with expiration capabilities. Given the volume of potential user records and the non-critical nature of this data, Redis serves as an appropriate storage solution. Each user's request count needs individual tracking, making interceptors the ideal mechanism for enforcement in Spring Boot applications.

When using Redis, key design becomes crucial. Since rate limiting involves both user identification and API endpoints, string concatenation provides a simple unique identifier. Using IP addresses (or authenticated user IDs) combined with URL paths creates keys in the format ip:url.

Code Implementation

@Component
public class RateLimitInterceptor implements HandlerInterceptor {
    
    @Autowired
    private AccessControlService redisService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        String endpoint = request.getRequestURI().substring(1);
        String clientIp = NetworkUtils.getClientIP(request);
        String cacheKey = String.format("rate:%s:%s", clientIp, endpoint);
        
        if (!redisService.validateAccess(cacheKey)) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(ResponseUtils.rateLimitExceeded());
            return false;
        }
        
        return true;
    }
}

@Service
public class AccessControlService {
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    public boolean validateAccess(String key) {
        Boolean isNew = redisTemplate.opsForValue().setIfAbsent(key, "10", 60, TimeUnit.SECONDS);
        
        if (isNew != null && isNew) {
            return true;
        }
        
        Long remaining = redisTemplate.opsForValue().decrement(key);
        return remaining != null && remaining >= 0;
    }
}

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    @Bean
    public RateLimitInterceptor rateLimiter() {
        return new RateLimitInterceptor();
    }
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(rateLimiter()).addPathPatterns("/**");
    }
}

For selective endpoint protection, custom annotations can be combined with interceptors.

Parameter Tampering Prevention

Request parameter tampering occurs when attackers intercept legitimate requests and modify parameters before forwarding. This requires server-side validation comparing original and received parameters.

Signature Validation Approach

Parameter signing involves generating a cryptographic signature from request parameters:

  1. Client sorts all parameters alphabetically and concatenates them into a string
  2. Applies cryptographic hashing (e.g., MD5) to create client signature
  3. Sends parameters and signature to server
  4. Server performs identical operations to generate server signature
  5. Compares signatures for validation

Frontend Implementation

function generateSignature(params) {
    const sortedKeys = Object.keys(params).sort();
    let signatureString = '';
    
    sortedKeys.forEach((key, index) => {
        if (index === 0) {
            signatureString += `${key}=${params[key]}`;
        } else {
            signatureString += `&${key}=${params[key]}`;
        }
    });
    
    return md5(signatureString).toUpperCase();
}

Backend Validation

@Component
public class SignatureValidationInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> cleanParams = new HashMap<>();
        
        for (String key : parameterMap.keySet()) {
            if (!"signature".equalsIgnoreCase(key)) {
                cleanParams.put(key, ArrayUtils.toString(parameterMap.get(key)));
            }
        }
        
        String clientSignature = request.getParameter("signature");
        String serverSignature = CryptoUtils.generateSignature(cleanParams);
        
        if (clientSignature == null || !clientSignature.equals(serverSignature)) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(ResponseUtils.invalidSignature());
            return false;
        }
        
        return true;
    }
}

Client-side JavaScript should be obfuscated to prevent algorithm exposure.

Request Time Sensitivity

Certain operations require time-bound validity, such as payment confirmations or transit passes. Combining rate limiting and signature validation with timestamp verification ensures requests remain valid within specified windows.

Implementation adds a timestamp parameter during request creation. The server compares this timestamp with current time, rejecting requests exceeding the validity period.

Transport Layer Encryption

HTTPS protocol encrypts communication between clients and servers using SSL/TLS certificates. Implementation involves:

  1. Acquiring SSL certificates from Certificate Authorities or generating self-signed certificates
  2. Configuring certificates in application servers
  3. Establishing encrypted communication channels
  4. Automatic encryption/decryption of request/response data

API Documentation Standards

API documentation facilitates collaboration between frontend and backend developers through standardized interface definitions.

Documentation Generations

  1. Static documentation files
  2. Interactive online platforms (ShowDoc)
  3. Automated documentation tools (Swagger)

Swagger Integration

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>
@Configuration
@EnableSwagger2
public class SwaggerConfiguration implements WebMvcConfigurer {
    
    @Bean
    public Docket apiDocumentation() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.organization.project.controller"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(documentationMetadata());
    }
    
    private ApiInfo documentationMetadata() {
        return new ApiInfoBuilder()
                .title("Project API Documentation")
                .description("Comprehensive API reference")
                .version("1.0.0")
                .build();
    }
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

Common annotations include @Api, @ApiOperation, @ApiImplicitParam, and @ApiModel for comprehensive API description.

Tags: API Security Rate Limiting Parameter Validation HTTPS swagger

Posted on Thu, 08 Oct 2026 16:09:26 +0000 by transformationstarts