Rapidoid - Extremely Fast, Simple and Powerful Java Web Framework!

Open source (Apache license). View benchmark... Community: [email protected]

  • Role-based security checks for the web handlers are supported out-of-the-box.
  • Accessing a protected page without the required roles/privileges will automatically display a nice login page.
  • Accessing a protected RESTful service without the required roles/privileges will return error in JSON format.
  • Required roles can be configured per route (e.g. On.get("/review").roles("moderator").json(...)).
  • Required roles for POJO handlers can configured with annotations (e.g. @Roles({"moderator", "administrator"})).
  • Rapidoid includes annotations for the common roles (@Administrator, @Moderator, @Manager, @LoggedIn).
  • The @Administrator annotation is equivalent to @Roles("administrator") or @Roles(Role.ADMINISTRATOR).
  • The @Manager annotation is equivalent to @Roles("manager") or @Roles(Role.MANAGER).
  • The @Moderator annotation is equivalent to @Roles("moderator") or @Roles(Role.MODERATOR).
  • The @LoggedIn annotation is equivalent to @Roles("logged_in") or @Roles(Role.LOGGED_IN).
  • App.bootstrap(args).auth() will bootstrap the built-in authentication handlers (POST /_login and GET /_logout).
  • A POST /_login request containing username and password will execute the (custom-configured or default) login handler.
  • If the login handler returns true, the user was authenticated and the authentication data (username and login expiration time) are saved in the token.
  • The token is returned by the POST /_login handler, but it is also persisted in the _token cookie.
  • With every request the authentication data is being sent through the token, so the server can identify the user.
  • When the browser is closed, the _token cookie expires, so the auth data is lost.
  • The token can be sent with a HTTP request as a _token cookie, or a _token parameter (in the URI or the body).
  • After a configurable time (config token.ttl in milliseconds), the authentication of the logged-in user expires.
  • A GET /_logout request will execute the built-in logout handler which clears the authentication data from the token.
  • The built-in GET /_logout handler might be changed to POST /_logout in future.
  • For the Admin.* API (which is a mirror of the On.* API, but for the Admin setup) the administrator role is configured by default.
import org.rapidoid.setup.App;
import org.rapidoid.setup.My;
import org.rapidoid.setup.On;
import org.rapidoid.u.U;
public class Main {
    public static void main(String[] args) {
        On.get("/").html((req, resp) -> "this is public!");
        On.get("/manage").roles("manager").html((req, resp) -> "this is private!");
        // Dummy login: successful if the username is the same as the password
        My.loginProvider((req, username, password) -> username.equals(password));
        // Gives the 'manager' role to every logged-in user
        My.rolesProvider((req, username) -> U.set("manager"));
import org.rapidoid.annotation.Controller;
import org.rapidoid.annotation.GET;
import org.rapidoid.security.Role;
import org.rapidoid.security.annotation.Administrator;
import org.rapidoid.security.annotation.Roles;
import org.rapidoid.u.U;
public class MyCtrl {
    @Roles({"manager", Role.MODERATOR})
    public Object hi() {
        return U.map("msg", "hi!");

Let's send some HTTP requests and check the results:

this is public!
GET /manage
GET /hi
{"error":"The user doesn't have the required roles!","code":403,"status":"Forbidden"}
POST /_login {"username":"foo","password":"wrong"}
POST /_login {"username":"foo","password":"foo"}
GET /manage
this is private!
GET /hi

HTTP server routes information:

Verb Path Zone Content type MVC View name Roles
GET / main html
POST /_login main json
GET /_logout main json logged_in
GET /hi main json
GET /manage main html manager