SpringBoot+Shiro权限管理
一、为什么要了解权限框架
权限管理框架属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则用户可以访问而且只能访问自己被授权的资源。
目前常见的权限框架有Shiro和Spring Security,本篇文章记录springboot整合shiro,实现简单的权限控制。
二、shiro介绍
Shiro全称是Apache Shiro,是一款灵活、强大的安全框架。方便简洁的处理身份认证、授权、加密等。
shiro的三个组件:
Subject 【主体】:指代当前用户【人、爬虫等】
SecurityManager【安全管理器】:管理所有的Subject、具体安全操作的真正执行者。
Reamls:本质是一个安全的DTO,用于进行权限、认证信息;
通过Subject来进行认证和授权,而Subject又委托给SecurityManager; 需要给Shrio的SecurityManager注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。
以下是一个简单的Spring Boot + Shiro
权限管理示例,包含以下步骤:
1. 创建 Spring Boot 项目
可以使用 Spring Initializr(https://start.spring.io/)创建一个新的 Spring Boot 项目,添加Web
和thymeleaf
依赖(用于示例中的简单页面展示)
2. 添加 Shiro 依赖
在pom.xml
文件中添加 Shiro 相关依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.7.1</version>
</dependency>
3. 创建实体类用户实体类(User)
public class User {private Long id;private String username;private String password;// 可以添加更多用户相关的属性,如角色列表等// 构造函数、Getter和Setter方法public User() {}public User(String username, String password) {this.username = username;this.password = password;}// Getter和Setter方法public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
4. 创建 Shiro 配置类
@Configuration
public class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);// 配置登录页面shiroFilterFactoryBean.setLoginUrl("/login");// 配置未授权访问页面shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");// 配置过滤器链Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 对静态资源放行filterChainDefinitionMap.put("/css/**", "anon");filterChainDefinitionMap.put("/js/**", "anon");// 登录页面放行filterChainDefinitionMap.put("/login", "anon");// 其他请求需要认证filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(userRealm());return securityManager;}@Beanpublic UserRealm userRealm() {return new UserRealm();}
}
5. 创建自定义 Realm
public class UserRealm extends AuthorizingRealm {// 模拟用户数据存储,可以替换为数据库查询private Map<String, User> userMap = new HashMap<>();public UserRealm() {userMap.put("user1", new User("user1", "password1"));userMap.put("admin", new User("admin", "adminpassword"));}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();// 这里可以根据用户角色等信息添加权限,示例简单处理if ("admin".equals(principals.getPrimaryPrincipal())) {authorizationInfo.addRole("admin");}return authorizationInfo;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;String username = usernamePasswordToken.getUsername();User user = userMap.get(username);if (user == null) {throw new UnknownAccountException("用户不存在");}return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());}
}
6. 创建控制器(Controller)
@Controller
public class LoginController {@PostMapping("/login")public String login(String username, String password, Model model) {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);return "redirect:/index";} catch (AuthenticationException e) {model.addAttribute("error", "用户名或密码错误");return "login";}}@GetMapping("/login")public String showLoginPage() {return "login";}@GetMapping("/unauthorized")public String unauthorized() {return "unauthorized";}@GetMapping("/index")public String index() {return "index";}
}
前端页面大家可以自己去实现了。
总结:实现了一个简单的Spring Boot + Shiro
权限管理系统,用户可以登录,并且根据角色(这里简单示例了普通用户和管理员)显示不同的内容。在实际应用中,需要将用户数据存储替换为数据库操作,并完善权限管理的逻辑。