Quickstart
Get ogiri integrated into your Spring Boot application in 5 minutes.
1. Add Dependency
Gradle (Kotlin DSL):
implementation("com.quantipixels.ogiri:ogiri-jpa:2.0.0")
Gradle (Groovy):
implementation 'com.quantipixels.ogiri:ogiri-jpa:2.0.0'
Maven:
<dependency>
<groupId>com.quantipixels.ogiri</groupId>
<artifactId>ogiri-jpa</artifactId>
<version>2.0.0</version>
</dependency>
Includes ogiri-core and spring-boot-starter-data-jpa transitively. Reduces boilerplate by ~70%.
Gradle (Kotlin DSL):
implementation("com.quantipixels.ogiri:ogiri-jdbc:2.0.0")
Gradle (Groovy):
implementation 'com.quantipixels.ogiri:ogiri-jdbc:2.0.0'
Maven:
<dependency>
<groupId>com.quantipixels.ogiri</groupId>
<artifactId>ogiri-jdbc</artifactId>
<version>2.0.0</version>
</dependency>
Includes ogiri-core and spring-boot-starter-jdbc transitively. No Hibernate, no @Entity. See JDBC setup.
Gradle (Kotlin DSL):
implementation("com.quantipixels.ogiri:ogiri-core:2.0.0")
Gradle (Groovy):
implementation 'com.quantipixels.ogiri:ogiri-core:2.0.0'
Maven:
<dependency>
<groupId>com.quantipixels.ogiri</groupId>
<artifactId>ogiri-core</artifactId>
<version>2.0.0</version>
</dependency>
For MongoDB, Redis, or custom persistence implementations.
2. Implement Required Interfaces
Ògiri requires two interfaces to connect with your application's user system and routing.
OgiriUserDirectory
Connects Ògiri to your user database:
@Component
class MyUserDirectory(private val userService: UserService) : OgiriUserDirectory {
override fun findById(id: Long): OgiriUser? = userService.getById(id)
override fun findByUsername(username: String): OgiriUser? = userService.getByUsername(username)
override fun findByEmail(email: String): OgiriUser? = userService.getByEmail(email)
override fun loadUserByUsername(username: String): OgiriUser =
userService.getByUsername(username) ?: throw UsernameNotFoundException(username)
override fun recordSuccessfulLogin(userId: Long) {
userService.recordLogin(userId)
}
}
@Component
public class MyUserDirectory implements OgiriUserDirectory {
private final UserService userService;
public MyUserDirectory(UserService userService) {
this.userService = userService;
}
@Override
public OgiriUser findById(Long id) {
return userService.getById(id);
}
@Override
public OgiriUser findByUsername(String username) {
return userService.getByUsername(username);
}
@Override
public OgiriUser findByEmail(String email) {
return userService.getByEmail(email);
}
@Override
public OgiriUser loadUserByUsername(String username) {
OgiriUser user = userService.getByUsername(username);
if (user == null) throw new UsernameNotFoundException(username);
return user;
}
@Override
public void recordSuccessfulLogin(Long userId) {
userService.recordLogin(userId);
}
}
RouteRegistry
Declares which routes bypass authentication:
@Component
class MyRouteRegistry : OgiriRouteRegistry {
override fun routes() = listOf(
OgiriRoute.post("/api/auth/login"),
OgiriRoute.post("/api/auth/register"),
OgiriRoute.get("/api/health"),
)
}
@Component
public class MyRouteRegistry implements OgiriRouteRegistry {
@Override
public List<OgiriRoute> routes() {
return List.of(
OgiriRoute.post("/api/auth/login"),
OgiriRoute.post("/api/auth/register"),
OgiriRoute.get("/api/health")
);
}
}
Token Persistence
If using ogiri-jpa, create a simple token entity extending OgiriBaseTokenEntity:
@Entity
@Table(name = "user_tokens")
class MyToken : OgiriBaseTokenEntity()
@Entity
@Table(name = "user_tokens")
public class MyToken extends OgiriBaseTokenEntity {}
Then create your repository adapter. See Database Integration for the complete setup with JPA, MongoDB, Redis, and custom implementations.
3. Issue Tokens on Login
@RestController
class AuthController(private val tokenService: OgiriTokenService<Token>) {
@PostMapping("/api/auth/login")
fun login(@RequestBody request: LoginRequest, response: HttpServletResponse): ResponseEntity<*> {
val user = authenticate(request.username, request.password)
val authHeader = tokenService.createNewAuthToken(user.id, "web")
response.appendAuthHeaders(authHeader)
return ResponseEntity.ok(mapOf("message" to "Login successful"))
}
}
@RestController
public class AuthController {
private final OgiriTokenService<Token> tokenService;
public AuthController(OgiriTokenService<Token> tokenService) {
this.tokenService = tokenService;
}
@PostMapping("/api/auth/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request, HttpServletResponse response) {
User user = authenticate(request.getUsername(), request.getPassword());
AuthHeader authHeader = tokenService.createNewAuthToken(user.getId(), "web");
AuthHeaderKt.appendAuthHeaders(response, authHeader);
return ResponseEntity.ok(Map.of("message", "Login successful"));
}
}
Done!
Ògiri auto-configures the security filter chain. Authenticated requests will have their tokens validated and rotated automatically.
Response headers after login:
access-token: <token-hash>
client: web
uid: 123
expiry: 2025-12-25T00:00:00Z
Client sends on subsequent requests:
access-token: <token-hash>
client: web
uid: 123
expiry: 2025-12-25T00:00:00Z
Optional: SPI Hooks
Ogiri provides optional SPI hooks and cache modules you can opt into as Spring beans or extra dependencies.
Hooks (implement as a @Component, no extra dependency needed):
OgiriAuditHook— Callbacks on login success/failure, token rotation, and revocation (integrate with your SIEM)OgiriRateLimitHook— Enforce rate limits before login and token creation (e.g., Bucket4j, Redis)
Both default to no-ops when no bean is present. When a bean is registered, the ogiri auto-configuration wires it into your OgiriTokenService via setter injection (setAuditHook / setRateLimitHook) automatically.
Token Lookup Cache (eliminates per-request DB reads for the same user/client):
ogiri-caffeine— In-process Caffeine cache. Add the dependency and setogiri.lookup.type: caffeine. Best for single-instance deployments.ogiri-redis— Shared Redis cache. Addogiri-redis+spring-boot-starter-data-redisand setogiri.lookup.type: redis. Required for multi-instance deployments where revocations must propagate across nodes.
See Token Lookup Cache for full setup instructions.
Next Steps
| Topic | Description |
|---|---|
| Configuration | Token rotation, cleanup schedules, batch windows |
| Token Lookup Cache | Caffeine and Redis cache modules, opt-in setup |
| Database Integration | JPA, MongoDB, Redis, custom implementations |
| Sub-tokens | Device tokens, chat tokens, API tokens |
| Authentication Flow | Request lifecycle, rotation policies, headers |
| Sample Applications | Complete Java and Kotlin examples |