Comprehensive Apache Shiro Tutorial: Introduction, Configuration, Realms, Authentication Strategies, Encryption, Salt, Authorization, Spring Integration, and Caching
This extensive guide explains Apache Shiro's core concepts, demonstrates how to set up simple authentication, configure various Realm types, apply multi‑realm authentication strategies, encrypt passwords with hashing and salting, implement custom authorization, integrate Shiro with Spring MVC, explore different login methods, use JSP tags for UI control, and enable caching with Ehcache, providing complete code examples throughout.
1. Shiro Introduction
Apache Shiro is an open‑source Java security framework offering authentication, authorization, cryptography, and session management with a clean, easy‑to‑use API.
1.1 Origin
Originally named JSecurity in 2004, the project was contributed to the Apache Software Foundation in 2008, renamed Shiro, and became a top‑level Apache project in 2010.
1.2 Core Features
Shiro handles user authentication, role‑based access control, session management (even without a web container), event handling, data aggregation, single sign‑on (SSO), and "remember‑me" services.
2. Simple Authentication Example
Download Shiro 1.7.1, create a Maven Java SE project, and add the shiro-all dependency.
Create shiro.ini with a user definition:
[users]
sang=123,admin
[roles]
admin=*Initialize the SecurityManager via IniSecurityManagerFactory , obtain a Subject , and perform login with UsernamePasswordToken . Use Subject.isAuthenticated() to check login status and Subject.logout() to log out.
3. Understanding Realms
A Realm acts as a bridge between Shiro and your application's security data. It provides authentication and authorization information from sources such as INI files, JDBC databases, LDAP, or custom implementations.
Example custom Realm implementation:
public class MyRealm implements Realm {
public String getName() { return "MyRealm"; }
public boolean supports(AuthenticationToken token) { return token instanceof UsernamePasswordToken; }
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { /* validate user */ }
}4. Realm Inheritance
To support authorization, extend AuthorizingRealm instead of AuthenticatingRealm . Implement doGetAuthenticationInfo for login and doGetAuthorizationInfo to supply roles and permissions.
5. Multi‑Realm Authentication Strategies
Shiro can use multiple Realms. The default strategy AtLeastOneSuccessfulStrategy succeeds if any Realm authenticates the user. Other strategies include AllSuccessfulStrategy (all Realms must succeed) and FirstSuccessfulStrategy (first successful Realm wins). Configure the strategy in shiro.ini .
6. Password Encryption
Use hash algorithms such as MD5 or SHA‑512 via Shiro's Md5Hash , Sha512Hash , or generic SimpleHash . Example:
Md5Hash md5Hash = new Md5Hash("123", null, 1024);Store the resulting hash in the database and configure a matching HashedCredentialsMatcher in the Realm.
7. Adding Salt to Passwords
Salting prevents identical passwords from producing identical hashes. Shiro supports salt via the SimpleHash constructor or by configuring JdbcRealm.saltStyle (e.g., COLUMN ) and providing a custom authentication query that returns the password and salt columns.
8. Custom Realm with Roles and Permissions
Implement doGetAuthorizationInfo to return a SimpleAuthorizationInfo containing role and permission sets. Example:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Set
roles = new HashSet<>();
Set
perms = new HashSet<>();
if ("sang".equals(principals.getPrimaryPrincipal())) {
roles.add("admin");
perms.add("book:update");
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
info.setStringPermissions(perms);
return info;
}9. Integrating Shiro with Spring MVC
Configure DefaultWebSecurityManager and ShiroFilterFactoryBean beans in Spring XML, set URLs for login, success, and unauthorized pages, and define filter chain definitions (e.g., /**=authc ).
In web.xml , add a DelegatingFilterProxy named shiroFilter to delegate all requests to Shiro.
10. Three Login Approaches
10.1 Custom Controller Login : Create a login form, read username/password, build UsernamePasswordToken , and call Subject.login() .
10.2 HTTP Basic Authentication : Set authcBasic in the filter chain; browsers prompt for credentials.
10.3 Form‑Based Authentication : Use Shiro’s built‑in form filter ( authc ), configure loginUrl , and handle login failures by checking the shiroLoginFailure request attribute.
11. Authorization by Roles and Permissions
Configure JdbcRealm.permissionsLookupEnabled=true to enable permission queries. In the filter chain, protect URLs with roles[admin] or perms[book:info] . Shiro will redirect unauthorized access to the configured unauthorizedUrl .
12. Shiro JSP Tags
Use tags such as <shiro:guest> , <shiro:user> , <shiro:principal/> , <shiro:hasRole name="admin"> , <shiro:lacksPermission name="book:info"> , etc., to conditionally display content based on authentication state, roles, or permissions.
13. Caching with Ehcache
Add the shiro‑ehcache dependency and an ehcache.xml configuration file. Define an EhCacheManager bean and inject it into the DefaultWebSecurityManager . Shiro will cache authentication and authorization data, reducing database hits.
Testing shows that after the first permission check, subsequent checks retrieve data from the cache instead of querying the database.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.