3. shiro- 权限认证
#在rememberMe的基础上修改CustomizeRealm
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
if (ObjectUtils.isEmpty(principals)){
throw new UnknownAccountException();
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//从pricipals中获取登入的用户信息
String username = principals.getPrimaryPrincipal().toString();
User user = userService.queryUser(username);
for (Role role : user.getRoles()) {
//获取角色,并给用户添加角色
info.addRole(role.getRole());
for (Perm perm : role.getPerms()) {
//获取角色对应的权限,并给用户添加权限
info.addStringPermission(perm.getPerm());
}
}
return info;
}
#添加一个controller
/**
* 在访问api时 shiro会根据@RequiresRoles和@RequiresPermission调用doGetAuthorizationInfo()
*/
@Slf4j
@RestController
//如果没有指定method,@RequestMapping会接收所有类型的请求
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
@RequiresRoles("admin")
@RequiresPermissions("user:add")
@PostMapping
public String save(User user) {
userService.save(user);
return "添加成功";
}
@RequiresPermissions("user:delete")
@RequiresRoles("admin")
@ResponseBody
@DeleteMapping("/{id}")
public String remove(@PathVariable("id") Integer id) {
userService.removeById(id);
return "删除成功";
}
@RequiresPermissions("user:update")
//logical.OR表示二者中的一个即可
@RequiresRoles(value = {"teacher","admin"},logical = Logical.OR)
@ResponseBody
@PutMapping
public String update(User user) {
userService.updateById(user);
return "更新成功";
}
@RequiresPermissions("user:select")
@ResponseBody
@GetMapping
public List<User> list() {
List<User> list = userService.list();
System.out.println(list);
return list;
}
@RequiresPermissions("user:select")
@RequiresRoles(value = {"teacher","student","admin"},logical = Logical.OR)
@GetMapping("/{id}")
public User get(@PathVariable("id") Integer id) {
//这里调用的只是mybatis-plus封装的方法所以不会打印出集合的信息
User user = userService.getById(id);
System.out.println(user);
return user;
}
}
#修改yml
mvc:
hiddenmethod:
filter:
enabled: true
#修改index.html
<!--templates下的只能通过controller访问-->
<a shiro:guest="" th:href="@{/login}">登入</a>
<form shiro:authenticated="" th:action="@{/user}" method="post">
<input type="text" name="name" placeholder="用户名">
<br>
<input type="password" name="password" placeholder="密码">
<br>
<input type="submit" value="添加用户">
</form>
<hr>
<form shiro:authenticated="" th:action="@{/user/}" method="post">
<input type="hidden" name="_method" value="delete">
<input type="text" name="id" placeholder="id">
<br>
<input type="submit" value="删除用户">
</form>
<hr>
<form shiro:authenticated="" th:action="@{/user}" method="post">
<input type="hidden" name="_method" value="PUT">
<br>
<input type="text" name="id" placeholder="id">
<br>
<input type="text" name="name" placeholder="用户名">
<br>
<input type="password" name="password" placeholder="密码">
<input type="submit" value="更新用户">
</form>
<hr>
<form shiro:authenticated="" th:action="@{/user}" method="get">
<input type="submit" value="查询所有用户">
</form>
<hr>
<form shiro:authenticated="" th:action="@{/user/}" method="get">
<input type="text" name="id" placeholder="id">
<br>
<input type="submit" value="查询用户">
</form>
<a th:href="@{/logout}">注销</a>
</body>
<script>
$("input[type='submit']").mousedown(function () {
var parent = $(this).parent();
var action = parent.attr("action");
console.log(action);
var children = parent.children("input[name='id']");
//children是一个数组
if (children.length == 0) {
return;
}
//拼接获取到的值
var jQuery = parent.attr("action", action + children.val());
console.log(jQuery)
});
#添加一个没有权限认证的异常处理器
@ControllerAdvice
public class ShiroHandler {
@ExceptionHandler(AuthorizationException.class)
private ModelAndView handleAuthorizationException(AuthorizationException e) {
HashMap<String, Object> map = new HashMap<>();
map.put("msg", "你没有权限这么做");
//如果要自定义传属性到getAttributes()中必须通过这种方法,不能通过@RequestStatus
map.put("javax.servlet.error.status_code", HttpStatus.FORBIDDEN.value());
return new ModelAndView("forward:/error", map);
}
}
相应的错误页面
<body>
<div>[[${msg}]]</div>
<a th:href="@{/index}">首页</a>
</body>