Apache Shiro 是一个强大且易于使用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能。它能够处理身份验证、授权、密码加密等工作,使得应用程序的安全性更加容易实现。
如果你使用的是 Maven 构建工具,可以在 pom.xml
文件中添加 Shiro 的依赖:
xml<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>最新版本号</version> <!-- 替换为实际需要的版本 -->
</dependency>
确保你已经选择了适合你项目的具体依赖。例如,如果你正在开发的是一个 Web 应用程序,上面的依赖是合适的。对于非 Web 应用,可能需要选择不同的 starter。
创建一个配置类来初始化 Shiro 的相关组件。以下是一个简单的示例:
javaimport org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
// 使用自定义的Realm,这里仅作为示例返回了一个新的IniRealm。
return new YourCustomRealm();
}
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 设置登录页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 设置成功登录后跳转的页面
shiroFilterFactoryBean.setSuccessUrl("/home");
// 设置未授权时跳转的页面
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
// 配置访问控制过滤器链
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/assets/**", "anon"); // 对静态资源允许匿名访问
filterChainDefinitionMap.put("/login", "anon"); // 允许匿名访问登录URL
filterChainDefinitionMap.put("/**", "authc"); // 所有其他请求都需要经过认证
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
在这个配置类中,我们定义了一个 Realm
实例,它是 Shiro 中用于安全数据源的核心部分,比如用户账户信息、角色和权限等。然后,我们将这个 Realm
注入到 SecurityManager
中,并通过 ShiroFilterFactoryBean
来配置 URL 过滤规则。
为了实现具体的认证逻辑,你需要创建一个继承自 AuthorizingRealm
的类,并重写其方法:
javaimport org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyCustomRealm extends AuthorizingRealm {
// 实现授权逻辑
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 根据用户名查找用户的角色和权限信息
return null; // 返回用户的角色和权限信息
}
// 实现认证逻辑
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名查找用户并验证密码
if (!"your_username".equals(username)) {
throw new AuthenticationException("用户名错误");
}
if (!"your_password".equals(password)) {
throw new AuthenticationException("密码错误");
}
// 如果验证通过,则返回包含用户信息的对象
return new SimpleAuthenticationInfo(username, password, getName());
}
}
在你的控制器中,你可以利用 Shiro 提供的标签或编程式 API 来检查用户的认证状态和权限:
javaimport org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/home")
public String home() {
return "Welcome to the home page!";
}
@GetMapping("/admin")
@RequiresRoles("admin") // 只有拥有 'admin' 角色的用户才能访问此方法
public String admin() {
return "Welcome to the admin page!";
}
@GetMapping("/logout")
public String logout() {
SecurityUtils.getSubject().logout();
return "You've been logged out.";
}
}