【Shiro 学习笔记】
Shiro 是一个强大而灵活的 Java 安全框架,用于身份验证、授权和会话管理。它提供了易于使用的 API,可以轻松地集成到现有的 Java 应用程序中。本文将介绍 Shiro 的基本概念和使用方法,并通过代码示例演示其在实际项目中的应用。
一、Shiro 的基本概念
1. 身份验证(Authentication):验证用户的身份,确保用户是合法的。
2. 授权(Authorization):决定用户是否有权限执行某个操作或访问某个资源。
3. 会话管理(Session Management):跟踪用户的会话状态,包括登录和注销。
4. 加密(Cryptography):保护用户的敏感信息,如密码。
二、Shiro 的使用步骤
1. 添加 Shiro 依赖:在项目的 pom.xml 文件中添加 Shiro 的依赖项。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
2. 配置 Shiro:创建一个 shiro.ini 文件,并在其中配置 Realm 和其他选项。
[main]
myRealm = com.example.MyRealm
[users]
admin = admin, admin
user = password, user
[roles]
admin = *
user = read
[urls]
/admin/** = authc, roles[admin]
/** = authc
3. 实现 Realm 接口:创建一个自定义的 Realm 类,用于验证用户身份和授权。
public class MyRealm implements Realm {
@Override
public String getName() {
return "myRealm";
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名和密码进行验证逻辑,可以查询数据库或其他数据源
// 如果验证成功,返回一个 SimpleAuthenticationInfo 对象
// 如果验证失败,抛出相应的异常
}
@Override
public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
// 根据用户名查询用户角色和权限信息,可以查询数据库或其他数据源
// 创建一个 SimpleAuthorizationInfo 对象,并设置角色和权限信息
}
}
4. 编写业务逻辑:在应用程序中编写代码来处理用户身份验证和授权。
// 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建一个 UsernamePasswordToken 对象,并设置用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 获取当前用户的 Subject 对象
Subject currentUser = SecurityUtils.getSubject();
try {
// 调用 Subject 的 login 方法进行身份验证
currentUser.login(token);
// 登录成功,继续其他操作
} catch (AuthenticationException e) {
// 登录失败,处理异常
}
5. 集成 Shiro:在应用程序中集成 Shiro。
// 创建一个 SecurityManager 对象,并设置自定义的 Realm
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(new MyRealm());
// 将 SecurityManager 设置到 SecurityUtils 中
SecurityUtils.setSecurityManager(securityManager);
// 在需要进行权限控制的地方,使用 Shiro 的注解添加访问控制
@RequiresRoles("admin")
public void doSomething() {
// 执行需要权限的操作
}
三、Shiro 示例演示
下面通过一个简单的示例来演示 Shiro 的使用。
1. 创建一个 Maven 项目,并添加 Shiro 依赖。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
2. 创建一个 shiro.ini 文件,配置 Realm 和权限控制。
[main]
myRealm = com.example.MyRealm
[users]
admin = admin, admin
user = password, user
[roles]
admin = *
user = read
[urls]
/admin/** = authc, roles[admin]
/** = authc
3. 创建一个 MyRealm 类,实现 Shiro 的 Realm 接口。
public class MyRealm implements Realm {
@Override
public String getName() {
return "myRealm";
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
if ("admin".equals(username) && "admin".equals(password)) {
return new SimpleAuthenticationInfo(username, password, getName());
} else if ("user".equals(username) && "password".equals(password)) {
return new SimpleAuthenticationInfo(username, password, getName());
} else {
throw new AuthenticationException("Invalid username or password");
}
}
@Override
public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
if ("admin".equals(username)) {
authorizationInfo.addRole("admin");
authorizationInfo.addRole("user");
} else if ("user".equals(username)) {
authorizationInfo.addRole("user");
}
authorizationInfo.addStringPermission("read");
return authorizationInfo;
}
}
4. 编写一个简单的 Web 项目,处理用户登录和权限控制。
// 在登录页面的表单提交后,获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建一个 UsernamePasswordToken 对象,并设置用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 获取当前用户的 Subject 对象
Subject currentUser = SecurityUtils.getSubject();
try {
// 调用 Subject 的 login 方法进行身份验证
currentUser.login(token);
// 登录成功,继续其他操作
} catch (AuthenticationException e) {
// 登录失败,处理异常
}
5. 在需要进行权限控制的地方,使用 Shiro 的注解进行访问控制。
@RequiresRoles("admin")
public void doSomething() {
// 执行需要权限的操作
}
总结、
本文简要介绍了 Shiro 的基本概念和使用步骤,并通过示例演示了 Shiro 在实际项目中的应用。Shiro 提供了一个简单而强大的安全解决方案,可以帮助我们轻松地实现身份验证和授权功能。希望本文能够对你理解和使用 Shiro 有所帮助。