完善之前的博客里的项目,本博客主要讲述Shiro的权限管理模块
代码实例
引入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
配置Shiro
java
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public SecurityManager securityManager(MyRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
Map<String, Filter> filters = new HashMap<>();
// 可以添加自定义的过滤器
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionMap = new HashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "authc");
ShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.setChainDefinitionMap(filterChainDefinitionMap);
shiroFilterFactoryBean.setFilterChainDefinitionMap(chainDefinition.getChainDefinitionMap());
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
自定义Realm
java
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService; // 假设有一个UserService用于查询用户信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.getPrimaryPrincipal();
// 查询用户权限和角色
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 假设从数据库中查询到的角色和权限
authorizationInfo.addRole("role1");
authorizationInfo.addStringPermission("user:delete");
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
// 查询用户信息
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户不存在");
}
// 返回验证信息
return new SimpleAuthenticationInfo(username, user.getPassword(), getName());
}
}
控制层
java
package com.bdqn.controller;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bdqn.pojo.Right;
import com.bdqn.pojo.Role;
import com.bdqn.service.RightService;
import com.bdqn.service.RoleService;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Controller
@RequestMapping("/role")
public class RoleController {
@Resource
private RoleService roleService;
@Resource
private RightService rightService;
/**
* 角色列表
*/
@RequiresPermissions("L0602")
@RequestMapping("/list")
public String list(Model model, String roleName, Long pageIndex) {
// 当前要查询的页码,如果是null则设置为默认查第1页
pageIndex = pageIndex == null ? 1 : pageIndex;
// 分页查询用户列表
Page page = new Page(pageIndex, 5L);
Page<Role> rolePager = roleService.findPage(roleName, page);
// 设置数据到作用域
model.addAttribute("roleName", roleName); // 数据回显
model.addAttribute("rolePager", rolePager);
// 跳转页面
return "role/list";
}
/**
* 去添加页
*/
@RequiresPermissions("L060201")
@GetMapping("/add")
public String toAdd(Model model) {
// 查找所有权限,用于指派权限
List<Right> rights = rightService.findAll();
// 设置数据到作用域
model.addAttribute("rights", rights);
// 跳转页面
return "role/add";
}
/**
* 检查用户名是否可用({"result":"true"} 表示已存在,不可用)
*/
@ResponseBody // REST风格,直接将数据写入响应流(对应Ajax请求)
@GetMapping("/check")
public String checkRoleName(String roleName, Long roleId) {
JSONObject json = new JSONObject();
if (roleName == null) {
json.put("result", "error");
return json.toJSONString();
}
// 判断角色名称是否可用(排除某个ID)
Role role = roleService.getByRoleNameExceptRoleId(roleName, roleId);
json.put("result", String.valueOf(role != null));
return json.toJSONString();
}
/**
* 跳转到修改页
*/
@RequiresPermissions("L060204")
@GetMapping("/edit")
public String toEdit(Model model, Long roleId) {
// 查找所有权限,用于指派权限
List<Right> rights = rightService.findAll();
// 根据ID获取角色信息
Role role = roleService.getById(roleId);
// 通过角色ID获取对应的权限集合
Set<Right> roleRights = rightService.findRightByRoleId(roleId);
role.setRights(roleRights); // 权限角色拥有的权限集合
// 将数据设置到作用域
model.addAttribute("rights", rights);
model.addAttribute("role", role);
// 跳转页面
return "role/edit";
}
/**
* 保存角色信息(权限映射关系先删除再添加)
*/
@RequiresPermissions("L060202")
@PostMapping("/save")
public String save(Role role, String[] rightCodes) {
System.out.println(role);
// 使用Lambda表达式打印数组信息
Arrays.stream(rightCodes).forEach(code -> System.out.print(code + ' '));
System.out.println();
// 保存角色及对应的权限(兼容添加和修改)
roleService.saveRoleAndRight(role, rightCodes);
// 重定向到列表页面
return "redirect:/role/list";
}
/**
* 删除角色
*/
@RequiresPermissions("L060203")
@ResponseBody
@PostMapping("/del/{roleId}")
public Map<String, Object> del(@PathVariable("roleId") Long roleId) {
Map<String, Object> map = new HashMap<>();
boolean result = false;
map.put("result", String.valueOf(result));
return map;
}
}
最后启动项目...