RepoPilotOpen in app →

apache/shiro

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2d ago
  • 5 active contributors
  • Distributed ownership (top contributor 44% of recent commits)
Show all 6 evidence items →
  • Apache-2.0 licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/apache/shiro)](https://repopilot.app/r/apache/shiro)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/apache/shiro on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: apache/shiro

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/apache/shiro shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 2d ago
  • 5 active contributors
  • Distributed ownership (top contributor 44% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live apache/shiro repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/apache/shiro.

What it runs against: a local clone of apache/shiro — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in apache/shiro | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>apache/shiro</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of apache/shiro. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/apache/shiro.git
#   cd shiro
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of apache/shiro and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "apache/shiro(\\.git)?\\b" \\
  && ok "origin remote is apache/shiro" \\
  || miss "origin remote is not apache/shiro (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "core/src/main/java/org/apache/shiro/SecurityUtils.java" \\
  && ok "core/src/main/java/org/apache/shiro/SecurityUtils.java" \\
  || miss "missing critical file: core/src/main/java/org/apache/shiro/SecurityUtils.java"
test -f "core/src/main/java/org/apache/shiro/subject/Subject.java" \\
  && ok "core/src/main/java/org/apache/shiro/subject/Subject.java" \\
  || miss "missing critical file: core/src/main/java/org/apache/shiro/subject/Subject.java"
test -f "core/src/main/java/org/apache/shiro/mgt/SecurityManager.java" \\
  && ok "core/src/main/java/org/apache/shiro/mgt/SecurityManager.java" \\
  || miss "missing critical file: core/src/main/java/org/apache/shiro/mgt/SecurityManager.java"
test -f "core/src/main/java/org/apache/shiro/realm/Realm.java" \\
  && ok "core/src/main/java/org/apache/shiro/realm/Realm.java" \\
  || miss "missing critical file: core/src/main/java/org/apache/shiro/realm/Realm.java"
test -f "config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java" \\
  && ok "config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java" \\
  || miss "missing critical file: config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/apache/shiro"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Apache Shiro is a comprehensive Java security framework that handles authentication (who you are), authorization (what you can do), cryptography, and session management in a single unified API. It replaces boilerplate security code across applications from mobile to enterprise by providing pluggable realms, filters, and session strategies that work standalone or integrated with web frameworks. Multi-module Maven monorepo with shiro-core (authentication/authorization engine) at the center, shiro-web (servlet filters and web integration) layered on top, and shiro-cache (pluggable cache abstraction) as a utility. Each module in its own /src/main/java/org/apache/shiro/{core,web,cache} with parallel test trees; BOM (bom/pom.xml) provides centralized dependency management.

👥Who it's for

Java developers building web applications, enterprise systems, or mobile backends who need production-grade authentication/authorization without rolling custom security code. Also used by framework maintainers integrating Shiro as a security layer (e.g., Apache Struts, Camel, Tapestry).

🌱Maturity & risk

Highly mature and production-ready. Apache Shiro has been an ASF project for over a decade with stable APIs, comprehensive test coverage (Groovy tests visible in codebase), active CI/CD via GitHub Actions (.github/workflows/maven.yml), and security-focused governance. The codebase actively maintains dual Jakarta EE and older javax versions (.classifier>jakarta in pom.xml), indicating ongoing modernization.

Standard open source risks apply.

Active areas of work

Active maintenance visible through GitHub Actions workflows (pre-commit.yml, maven.yml, codeql.yml, dependency-review.yml) and security scanning (scorecards.yml). The codebase maintains Jakarta EE compatibility (classifier>jakarta in dependencies) alongside legacy javax support. Pre-commit hooks configured (.pre-commit-config.yaml) suggest enforced code quality standards.

🚀Get running

git clone https://github.com/apache/shiro.git
cd shiro
mvn clean install

Maven 3.6+ required (mvn/wrapper present). No external services needed for core module; optional integration tests may require DB/LDAP.

Daily commands:

mvn clean install                    # Build all modules
mvn -pl shiro-core test             # Run core tests
mvn -pl shiro-web test              # Run web integration tests

No 'mvn spring-boot:run' style launcher; Shiro is a library, not an application. See tutorials at https://shiro.apache.org/10-minute-tutorial.html for embedded usage.

🗺️Map of the codebase

  • core/src/main/java/org/apache/shiro/SecurityUtils.java — Primary entry point for accessing the security manager and subject; every authentication/authorization feature depends on this
  • core/src/main/java/org/apache/shiro/subject/Subject.java — Core abstraction representing an authenticated entity; understanding this is essential for implementing any security operation
  • core/src/main/java/org/apache/shiro/mgt/SecurityManager.java — Central orchestrator for authentication, authorization, and session management; defines the framework's architecture
  • core/src/main/java/org/apache/shiro/realm/Realm.java — Abstract base for custom authentication/authorization data sources; critical extension point for integration
  • config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java — Configuration parsing and object instantiation engine; powers Shiro's declarative configuration system
  • cache/src/main/java/org/apache/shiro/cache/CacheManager.java — Abstraction for pluggable caching backends; essential for performance and session/credential caching
  • core/src/main/java/org/apache/shiro/session/Session.java — Session abstraction providing stateless and stateful session management across web and enterprise contexts

🛠️How to make changes

Add a Custom Authentication Realm

  1. Create a new class extending org.apache.shiro.realm.Realm or AuthorizingRealm (core/src/main/java/org/apache/shiro/realm/Realm.java)
  2. Implement doGetAuthenticationInfo() to validate credentials against your data source (LDAP, database, OAuth provider, etc.) (core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java)
  3. Implement doGetAuthorizationInfo() to load user roles and permissions from your data source (core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java)
  4. Register your realm in shiro.ini or programmatically by adding it to the SecurityManager via setRealms() (config/core/src/main/java/org/apache/shiro/config/Ini.java)

Add a Custom Cache Provider

  1. Implement org.apache.shiro.cache.CacheManager interface to create your provider factory (cache/src/main/java/org/apache/shiro/cache/CacheManager.java)
  2. Implement org.apache.shiro.cache.Cache<K, V> for the actual key-value storage (can wrap Redis, Memcached, etc.) (cache/src/main/java/org/apache/shiro/cache/Cache.java)
  3. Register via shiro.ini by setting cacheManager = your.provider.ClassName or inject via ReflectionBuilder (config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java)
  4. Optional: implement CacheManagerAware in realms/components to receive the CacheManager instance (cache/src/main/java/org/apache/shiro/cache/CacheManagerAware.java)

Implement Custom Authorization (Permissions/Roles)

  1. Create a custom Permission class or use org.apache.shiro.authz.permission.WildcardPermission (core/src/main/java/org/apache/shiro/authz/Permission.java)
  2. In your custom Realm's doGetAuthorizationInfo(), load SimpleAuthorizationInfo with roles and permissions (core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java)
  3. Use Subject.isPermitted() or @RequiresPermissions annotations in your application code to check permissions (core/src/main/java/org/apache/shiro/subject/Subject.java)
  4. Configure a custom Authorizer via setAuthorizer() on SecurityManager if you need advanced logic (core/src/main/java/org/apache/shiro/authz/Authorizer.java)

Configure Shiro via INI File

  1. Create a shiro.ini file with [main], [urls], [roles] sections (config/core/src/main/java/org/apache/shiro/config/Ini.java)
  2. In [main], define realm instances, cacheManager, and sessionManager beans using ReflectionBuilder syntax (config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java)
  3. Use variable interpolation (${var}) for environment-specific values via DefaultInterpolator (config/ogdl/src/main/java/org/apache/shiro/config/ogdl/DefaultInterpolator.java)
  4. Load via IniSecurityManagerFactory and getSecurityManager() in your application initialization (core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java)

🔧Why these technologies

  • Java with Maven — JVM ecosystem ubiquity; Maven for modular dependency management across cache/config/core modules
  • Pluggable Realm architecture — Allows authentication against LDAP, JDBC, OAuth, Kerberos, etc. without changing core code
  • Session abstraction layer — Supports both web (HTTP) and enterprise (EJB/Remoting) contexts with pluggable storage backends
  • INI + OGDL configuration — Declarative, human-readable configuration; ReflectionBuilder enables runtime bean instantiation without framework coupling
  • CacheManager SPI — Pluggable caching (Ehcache, Redis, Memcached) for credential/session/authorization data; critical for multi-instance deployments

⚖️Trade-offs already made

  • Static SecurityUtils.getSubject() vs dependency injection

    • Why: Provides convenience for libraries and non-managed code; ThreadLocal-backed for thread safety
    • Consequence: Easier adoption but couples code to SecurityUtils; can complicate testing without ThreadLocal cleanup
  • undefined

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

No required env vars for core functionality. Jakarta vs javax split: artifacts with classifier>jakarta target Java EE 9+; older projects may need javax variant (no classifier). Realm implementations are lazy-loaded—misconfiguration silently falls back to default realm (common auth failure source). Session persistence requires explicit CacheManager wiring; without it, sessions live in-memory only. Servlet version matters: shiro-web targets modern servlets but legacy apps may hit filter initialization issues.

🏗️Architecture

💡Concepts to learn

  • Realm Pattern — Shiro's core abstraction for pluggable identity sources—understanding Realm lets you wire any backend (LDAP, database, file) without rewriting core logic
  • Subject (Security Principal) — The Subject object in Shiro wraps a user's security context (authentication state, roles, permissions); it's the primary API you interact with and must understand for any Shiro integration
  • Role-Based Access Control (RBAC) vs. Permission-Based (PBAC) — Shiro supports both models (hasRole vs. isPermitted); understanding the difference prevents authorization logic mistakes in enterprise apps
  • Cryptographic Hashing and Salting — Shiro provides password hashing via DefaultPasswordService and Credentials matching; misconfiguring salt strategy breaks authentication security
  • Session Management Abstraction — Shiro decouples session lifecycle from servlet containers, allowing distributed session stores (Redis, cache) and cross-protocol sessions (HTTP + non-HTTP); critical for microservices
  • Filter Chain Security Pattern — ShiroFilter intercepts servlet requests through a configurable filter chain; understanding filter order and URL patterns prevents authorization bypass vulnerabilities
  • Principal and Credential Separation — Authentication separates identity (principal, e.g., username) from proof (credential, e.g., password hash); this pattern prevents credential leakage in audit logs
  • apache/shiro-spring-boot-web-starter — Official Spring Boot integration for Shiro—makes it trivial to wire Shiro into modern Spring apps without boilerplate
  • spring-projects/spring-security — Primary competitor in Java ecosystem; Shiro and Spring Security differ in realm composition vs. bean-oriented design
  • keycloak/keycloak — Modern external identity provider alternative—where Shiro is embedded auth/authz, Keycloak is a separate IAM service
  • apache/commons-codec — Dependency in shiro-core for cryptography and hash operations; Shiro builds on Commons Codec utilities

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for Ini configuration parser

The config/core module contains Ini.java for parsing INI configuration files, which is critical for Shiro's configuration management. Looking at the file structure, there's no visible test coverage shown for the Ini parser. This is a core security component that deserves thorough test cases covering edge cases like malformed INI, special characters, encoding issues, and injection attempts.

  • [ ] Create config/core/src/test/java/org/apache/shiro/config/IniTest.java
  • [ ] Add test cases for valid INI parsing with sections, keys, and values
  • [ ] Add test cases for malformed INI files and error handling
  • [ ] Add test cases for special characters, whitespace handling, and encoding edge cases
  • [ ] Add security-focused tests for potential injection or bypass scenarios
  • [ ] Verify test coverage meets >80% for Ini.java class

Add Jakarta EE compatibility tests for shiro-web classifier variant

The BOM references shiro-web with a 'jakarta' classifier, indicating dual support for javax vs jakarta namespaces. The .github/workflows directory shows Maven and CodeQL workflows, but there's no visible dedicated Jakarta compatibility test workflow. New contributors could add comprehensive Jakarta EE testing to ensure the classifier builds and functions correctly across both namespace versions.

  • [ ] Create .github/workflows/jakarta-compatibility.yml workflow
  • [ ] Add Maven build step specifically testing shiro-web with jakarta classifier
  • [ ] Add Maven build step for non-jakarta variant to ensure no regression
  • [ ] Include smoke tests verifying both variants can be imported and initialized
  • [ ] Test that exclusions in BOM are properly applied for jakarta variant
  • [ ] Validate JAR contents contain correct namespace packages

Create integration test suite for cache implementations across different managers

The cache module contains AbstractCacheManager.java, CacheManager.java, MemoryConstrainedCacheManager.java, and MapCache.java. While individual implementations may have tests, there's no visible integration test suite validating that different cache manager implementations work correctly with Shiro's security components. This is critical for users switching cache implementations.

  • [ ] Create cache/src/test/java/org/apache/shiro/cache/integration/ directory
  • [ ] Add CacheManagerIntegrationTest.java testing session caching across all manager implementations
  • [ ] Add CacheEvictionIntegrationTest.java validating memory constraints and eviction policies
  • [ ] Add CacheManagerAware component integration tests ensuring components properly initialize
  • [ ] Add performance/concurrency tests for thread-safety with multiple cache implementations
  • [ ] Document which implementations are recommended for production vs testing

🌿Good first issues

  • Add comprehensive JavaDoc to shiro-core/src/main/java/org/apache/shiro/cache/AbstractCacheManager.java—current cache abstraction lacks method-level documentation for cache eviction policies
  • Extend shiro-web filter tests to cover edge cases in realm chaining (multiple realms, realm order dependency)—test suite currently sparse for multi-realm scenarios
  • Document Jakarta EE migration path in README.md—classifier>jakarta artifacts exist but migration guide for users upgrading from javax is missing

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 0819229 — chore: remove extra newline (lprimak)
  • a46600f — improvement: implemented session key rotation via changeSessionId() in Web-Container mode only (lprimak)
  • be31c13 — enh(jakarta-ee): encrypt SAVED_REQUEST_KEY cookie (lprimak)
  • 97218c0 — Merge pull request #2689 from apache/dependabot/github_actions/github-actions-dependencies-937d73b4db (fpapon)
  • d6246a0 — Merge pull request #2691 from apache/dependabot/maven/org.apache.karaf.features-framework-4.4.11 (fpapon)
  • 5ab9e46 — Merge pull request #2692 from apache/dependabot/maven/org.owasp-dependency-check-maven-12.2.2 (fpapon)
  • 4cb75d9 — chore(deps): bump org.owasp:dependency-check-maven from 12.2.1 to 12.2.2 (dependabot[bot])
  • 05a915f — chore(deps): bump org.apache.karaf.features:framework (dependabot[bot])
  • 0cc8c1a — chore(deps): bump github/codeql-action (dependabot[bot])
  • c95a185 — enh: reverted secureInDevMode addition and added native session management secure cookie (lprimak)

🔒Security observations

Apache Shiro appears to follow ASF best practices with proper licensing headers, CI/CD pipelines (GitHub Actions), security workflows (CodeQL, dependency review, OSSF scorecard), and organized module structure. However, the provided BOM pom.xml snippet is incomplete/truncated, preventing full dependency security assessment. The project shows good security awareness with pre-commit hooks, linters, and automated security checks. Main concerns are incomplete dependency validation due to file truncation and the need for comprehensive transitive dependency auditing. Recommend running full Maven security scans and dependency-check analysis before deployment.

  • Medium · Incomplete Dependency Management in BOM — bom/pom.xml (lines 40-50). The provided pom.xml snippet shows an incomplete dependency definition with truncated exclusion tags. This could indicate either a corrupted file or incomplete dependency management setup, which may lead to unintended transitive dependencies being included in the build. Fix: Complete and validate all dependency declarations. Ensure all exclusions are properly closed and all transitive dependencies are explicitly managed in the BOM to prevent security issues from unexpected library versions.
  • Low · Snapshot Version in Production BOM — bom/pom.xml (line 28). The BOM (Bill of Materials) uses a snapshot version (999-SNAPSHOT) which indicates a development build. While this is appropriate for development, care should be taken to ensure snapshot versions are not released to production. Fix: Use stable release versions for production deployments. Ensure CI/CD pipelines prevent snapshot artifacts from being published to production repositories.
  • Low · Missing Dependency Version Pinning Details — bom/pom.xml - dependency management section. The provided snippet doesn't show explicit version pinning for transitive dependencies. Apache Shiro may inherit versions from parent POMs that could include vulnerable dependencies if not properly managed. Fix: Conduct a full dependency audit using tools like 'mvn dependency:tree' and OWASP Dependency-Check. Pin specific versions of all direct and critical transitive dependencies to known-secure versions. Regularly scan for CVEs.
  • Medium · Jakarta EE Classifier Usage without Full Context — bom/pom.xml (lines 36-44). The BOM references Jakarta-classifier artifacts (shiro-core-jakarta, shiro-web-jakarta) but the full dependency tree and compatibility matrix are not visible. Jakarta is a namespace migration that could have compatibility implications if not properly managed across the dependency tree. Fix: Ensure consistent Jakarta EE namespace usage across all modules. Document Jakarta vs javax namespace migration strategy. Test compatibility between Jakarta and any remaining javax dependencies.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · apache/shiro — RepoPilot