Apache Shiro is a powerful and easy-to-use Java security framework that provides authentication, authorization, cryptography, and session management. Below is a step-by-step guide on how to use Apache Shiro for authentication in a Java application.
1. Add Apache Shiro Dependency
Add the Apache Shiro dependency to your project. If you’re using Maven, include the following in your pom.xml
:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.12.0</version> <!-- Use the latest version -->
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.12.0</version> <!-- Use the latest version -->
</dependency>
For Gradle, add the following to your build.gradle
:
implementation 'org.apache.shiro:shiro-core:1.12.0'
implementation 'org.apache.shiro:shiro-web:1.12.0'
2. Configure Shiro
Create a shiro.ini
file to define your security configuration. This file typically includes realms, users, roles, and permissions.
Example shiro.ini
:
[main]
# Define a realm (e.g., for in-memory users)
myRealm = org.apache.shiro.realm.text.IniRealm
myRealm.users = user1=password123,role1 \n user2=password456,role2
# Set the realm
securityManager.realms = $myRealm
[urls]
# Define URL-specific security rules /login = anon /logout = logout /** = authc
3. Initialize Shiro in Your Application
Initialize Shiro in your Java application by loading the shiro.ini
configuration.
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
public class ShiroExample {
public static void main(String[] args) {
// Load the Shiro configuration
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// Get the current user
Subject currentUser = SecurityUtils.getSubject();
// Simulate a login
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("user1", "password123");
token.setRememberMe(true); // Optional: remember the user
try {
currentUser.login(token);
System.out.println("Login successful!");
} catch (Exception e) {
System.out.println("Login failed: " + e.getMessage());
}
}
// Check if the user has a role
if (currentUser.hasRole("role1")) {
System.out.println("User has role1!");
} else {
System.out.println("User does not have role1.");
}
// Logout
currentUser.logout();
}
}
4. Integrate with a Web Application
If you’re using Shiro in a web application, configure it in your web.xml
:
<context-param>
<param-name>shiroConfigLocations</param-name>
<param-value>classpath:shiro.ini</param-value>
</context-param>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5. Custom Realm (Optional)
For more advanced use cases, you can create a custom realm to authenticate users against a database or other data source.
Example custom realm:
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
public class MyCustomRealm extends AuthenticatingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = new String(upToken.getPassword());
// Authenticate against your data source (e.g., database)
if ("user1".equals(username) && "password123".equals(password)) {
return new SimpleAuthenticationInfo(username, password, getName());
} else {
throw new AuthenticationException("Invalid credentials");
}
}
}
Update shiro.ini
to use the custom realm:
[main]
myRealm = com.example.MyCustomRealm
securityManager.realms = $myRealm
6. Testing and Debugging
- Run your application and test the authentication flow.
- Use logging to debug any issues (e.g., enable Shiro logging in
log4j.properties
orlogback.xml
).
Key Features of Shiro
- Authentication: Verify user identity.
- Authorization: Control access to resources based on roles and permissions.
- Session Management: Manage user sessions across environments.
- Cryptography: Secure data with hashing and encryption.
By following these steps, you can integrate Apache Shiro into your Java application for robust authentication and security.