Learn Quarkus - Basic Security & Auth
Episode 12 of 24

Learn Quarkus - Basic Security & Auth

This episode covers Quarkus security basics: HTTP authentication, role-based access control and identity stores, authentication mechanism configuration, as well as CSRF, CORS, and secure headers protection.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

A public API without protection is an invitation for abuse. Security isn't an add-on feature — it's a layer that's built into the application from the start. Before discussing OAuth2 and JWT in episode 13, you need to understand the security foundations in Quarkus.

Episode 12 covers the security basics: HTTP authentication, role-based access control and identity stores, authentication mechanism configuration, as well as CSRF, CORS, and secure headers protection.

An Introduction to Quarkus Security and HTTP Authentication

The Security Architecture

Quarkus Security has three components: an Identity Provider that authenticates users, authorization that determines access rights, and security annotations for declaring rules. Quarkus supports several mechanisms: basic, form-based, and bearer token.

HTTP Basic Authentication

The simplest way — credentials are sent in the Authorization: Basic ... header:

Enabling basic auth
quarkus.http.auth.basic=true

Property-Based Identity Store

For development, Quarkus provides an identity store backed by property files:

Property-based identity store
quarkus.security.users.file.enabled=true
quarkus.security.users.file.plain-text=true
quarkus.security.users.file.users=users.properties
quarkus.security.users.file.roles=roles.properties

Create src/main/resources/users.properties containing admin=admin123 and user=user123, then roles.properties containing admin=admin,user and user=user. This is enough for development and prototyping. For production, use a database-based identity store or OIDC (episode 13).

Role-Based Access Control and Identity Stores

Security Annotations

After authentication, access control is declared with annotations:

JavaProtecting a resource with roles
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
 
@Path("/api/admin")
public class AdminResource {
 
    @GET
    @RolesAllowed("admin")
    public String rahasia() {
        return "Hanya admin yang bisa melihat ini";
    }
}

@RolesAllowed("admin") restricts the endpoint to users with the admin role. Users without the role receive a 403 Forbidden.

Identity Store with JDBC

For real applications, store users in a database. Add the extension:

Adding the security-jdbc extension
./mvnw quarkus:add-extension -Dextensions=security-jdbc

Configure queries against the user tables:

JDBC identity store
quarkus.datasource.db-kind=h2
quarkus.security.jdbc.enabled=true
quarkus.security.jdbc.principal-query.sql=\
  SELECT password FROM users WHERE username = ?
quarkus.security.jdbc.principal-query.clear-password-mapper.enabled=true
quarkus.security.jdbc.principal-query.clear-password-mapper.password-index=1
quarkus.security.jdbc.principal-query.roles-query.sql=\
  SELECT role FROM user_roles WHERE username = ?

With security-jdbc, authentication validates the password against the users table and loads roles from the user_roles table. Always use password hashing in production — never store plain text.

Authentication Mechanism Configuration

HTTP Permissions

Besides per-endpoint annotations, Quarkus supports path-based rules in configuration:

HTTP permission by path
quarkus.http.auth.policy.only-admin.policy=role-based
quarkus.http.auth.policy.only-admin.roles=admin
quarkus.http.auth.permission.admin-route.paths=/api/admin/*
quarkus.http.auth.permission.admin-route.policy=only-admin

This configuration protects all /api/admin/* paths for the admin role only — without touching Java code.

Authentication Status

You can read the identity of an authenticated user: inject SecurityIdentity, then identity.getPrincipal().getName() returns the username of the currently logged-in user. SecurityIdentity also exposes roles via identity.getRoles().

CSRF, CORS, and Secure Headers Protection

CORS Configuration

CORS governs which domains are allowed to call your API from a browser:

CORS configuration
quarkus.http.cors=true
quarkus.http.cors.origins=https://app.kalian.com
quarkus.http.cors.methods=GET,POST,PUT,DELETE
quarkus.http.cors.headers=Content-Type,Authorization

Don't set origins=* unless absolutely necessary — it opens your API to every domain.

Secure Headers and CSRF

Quarkus provides secure headers automatically through the already-installed vertx-http extension: X-Content-Type-Options, X-Frame-Options, and Strict-Transport-Security. Customize them:

Configuring secure headers
quarkus.http.header."X-Content-Type-Options".value=nosniff
quarkus.http.header."Strict-Transport-Security".value=\
  max-age=31536000; includeSubDomains

Token-based APIs aren't vulnerable to CSRF because tokens aren't sent automatically by the browser. For cookie-based applications, use an anti-CSRF token pattern: the server issues a random token, the client sends it in a header during data mutations, and the server validates it before processing.

Testing Security

Run the application with basic auth enabled:

Testing authentication
curl -u admin:admin123 http://localhost:8080/api/admin
curl -i http://localhost:8080/api/admin
curl -u user:user123 http://localhost:8080/api/admin

The command curl -u admin:admin123 http://localhost:8080/api/admin sends basic auth credentials. Without credentials, the server returns 401; with a user lacking the admin role, it returns 403.

Wrap-Up

Episode 12 installs the first security layer of your application: understanding the Quarkus security architecture, role-based access control with annotations and HTTP permissions, authentication mechanism configuration, as well as CORS, CSRF, and secure headers protection.

Key takeaways:

  • Quarkus Security consists of authentication, authorization, and security annotations.
  • @RolesAllowed("admin") restricts access based on roles.
  • An identity store can come from properties, a JDBC database, or OIDC.
  • HTTP permissions protect paths without changing code.
  • CORS restricts which domains may call your API.
  • Don't store plain text passwords; always hash them in production.
  • Secure headers strengthen your defenses at the HTTP level.

In episode 13 we'll cover OAuth2/OIDC and JWT — Quarkus OIDC integration with an external identity provider, implementing JWT authentication and authorization, service-to-service auth with token introspection, as well as token storage and refresh best practices.

Learn Quarkus - Basic Security & Auth | Learn Quarkus