Automate Access Control for User-Specific Entities

Practically every web application is supposed to have multiple users and each user has some data – posts, documents, messages, whatever. And the most obvious thing to do is to protect these entities from being obtained by users that are not the rightful owners of these resources. Unfortunately, this is not the easiest thing to do. I don’t mean it’s hard, it’s just not as intuitive as simply returning the resources. When you are your /record/{recordId} endpoint, a database query for the recordId is the immediate thing you do. Only then comes the concern of checking whether this record belongs to the currently authenticated user. Frameworks don’t give you a hand here, because this access control and ownership logic is domain-specific. There’s no obvious generic way to define the ownership. It depends on the entity model and the relationships between entities. In some cases it can be pretty complex, involving a lookup in a join table (for many-to-many relationships). But you should automate this, for two reasons. First, manually doing these checks on every endpoint/controller method is tedious and makes the code ugly. Second, it’s easier to forget to add these checks, especially if there are new developers. You can do these checks in several places, all the way to the DAO, but in general you should fail as early as possible, so these checks should be on a controller (endpoint handler) level. In the case of Java and Spring, you can use annotations and a HandlerInterceptor to automate this. In case of any other language or framework, there are similar approaches available – some pluggable way to describe...

Basic API Rate-Limiting

It is likely that you are developing some form of (web/RESTful) API, and in case it is publicly-facing (or even when it’s internal), you normally want to rate-limit it somehow. That is, to limit the number of requests performed over a period of time, in order to save resources and protect from abuse. This can probably be achieved on web-server/load balancer level with some clever configurations, but usually you want the rate limiter to be client-specific (i.e. each client of your API sohuld have a separate rate limit), and the way the client is identified varies. It’s probably still possible to do it on the load balancer, but I think it makes sense to have it on the application level. I’ll use spring-mvc for the example, but any web framework has a good way to plug an interceptor. So here’s an example of a spring-mvc interceptor: @Component public class RateLimitingInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = LoggerFactory.getLogger(RateLimitingInterceptor.class); @Value("${rate.limit.enabled}") private boolean enabled; @Value("${rate.limit.hourly.limit}") private int hourlyLimit; private Map<String, Optional<SimpleRateLimiter>> limiters = new ConcurrentHashMap<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!enabled) { return true; } String clientId = request.getHeader("Client-Id"); // let non-API requests pass if (clientId == null) { return true; } SimpleRateLimiter rateLimiter = getRateLimiter(clientId); boolean allowRequest = limiter.tryAcquire(); if (!allowRequest) { response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value()); } response.addHeader("X-RateLimit-Limit", String.valueOf(hourlyLimit)); return allowRequest; } private SimpleRateLimiter getRateLimiter(String clientId) { if (limiters.containsKey(clientId)) { return limiters.get(clientId); } else { synchronized(clientId.intern()) { // double-checked locking to avoid multiple-reinitializations if (limiters.containsKey(clientId)) { return limiters.get(clientId); } SimpleRateLimiter rateLimiter = createRateLimiter(clientId); limiters.put(clientId, rateLimiter); return rateLimiter; } } } @PreDestroy public void...

Traditional Web Apps And RESTful APIs

When we are building web applications these days, it is considered a best practice to expose all our functionality as a RESTful API and then consume it ourselves. This usually goes with a rich front-end using heavy javascript, e.g. Angular/Ember/Backbone/React. But a heavy front-end doesn’t seem like a good default – applications that require the overhead of a conceptually heavy javascript framework are actually not in the majority. The web, although much more complicated, is still not just about single-page applications. Not to mention that if you are writing a statically-typed backend, you would either need a dedicated javascript team (no necessarily a good idea, especially in small companies/startups), or you have to write in that … not-so-pleasant language. And honestly, my browsers are hurting with all that unnecessary javascript everywhere, but that’s a separate story. The other option for having yourself consume your own RESTful API is to have a “web” module, that calls your “backend” module. Which may be a good idea, especially if you have different teams with different specialties, but the introduction of so much communication overhead for the sake of the separation seems at least something one should think twice before doing. Not to mention that in reality release cycles are usually tied, as you need extra effort to keep the “web” and “backend” in proper sync (“web” not requesting services that the “backend” doesn’t have yet, or the “backend” not providing a modified response model that the “web” doesn’t expect). As in my defence of monoliths, I’m obviously leaning towards a monolithic application. I won’t repeat the other post, but the idea is...