此篇博客为《SpringBoot学习笔记23——整合Shiro完成登录检验》后续部分,完成对接口的的权限校验
在上一篇代码中已经给出了验证校验类的代码 MyShiroRealm.java其中包含了如下代码:
/**
* 设置授权信息,目前这个方法没有什么作用
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
logger.info("开始授权(doGetAuthorizationInfo)");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//角色
// Set<String> roles = new HashSet<>();
// roles.add("role1");
// authorizationInfo.setRoles(roles);
//权限
Set<String> permissions = new HashSet<>();
permissions.add("user:list");
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
这部分代码就是用来做接口权限校验的。
用起来也不复杂,只是使用到了 @RequiresPermissions 注解
1.在controller中加入此注解@RequiresPermissions("contacter:findByPage")
package com.youyou.address.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youyou.address.entity.ContacterDO;
import com.youyou.address.service.ContacterService;
import com.youyou.address.vo.ContacterVO;
import com.youyou.common.base.BaseController;
import com.youyou.common.http.ResponseMessage;
import com.youyou.common.http.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 联系人controller
*
* @author: 刘朋
* <br/>date: 2018-11-06
*/
@Api(description = "联系人接口")
@RestController
@RequestMapping(value = "/${restPath}/address/contacter")
public class ContacterController extends BaseController<ContacterService, ContacterDO, ContacterVO> {
@ApiOperation(value = "分页查询")
@GetMapping("/findByPage")
@RequiresPermissions("contacter:findByPage")
public ResponseMessage<IPage<ContacterVO>> selectPage(int pageNo, int pageSize, ContacterVO vo) {
QueryWrapper<ContacterDO> queryWrapper = new QueryWrapper<>();
String name = vo.getName();
if(StringUtils.isNotBlank(name)){
queryWrapper.like("name", name);
}
IPage<ContacterDO> contacterDOIPage = service.queryPageOrderByCreateTimeDesc(pageNo, pageSize, queryWrapper);
IPage<ContacterVO> vIPage = getVPage(contacterDOIPage);
return Result.success(vIPage);
}
}
2.还需要添加一个异常处理类,这个是可有可无的 ,以下代码包含个人代码可自行修改。
package com.youyou.advice;
import com.youyou.common.http.ResponseMessage;
import com.youyou.common.http.Result;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
@Order(value = 1)
public class ShiroExceptionAdvice {
/**
* 创建LOG对象
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ShiroExceptionAdvice.class);
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler({ AuthenticationException.class, UnknownAccountException.class,
UnauthenticatedException.class, IncorrectCredentialsException.class })
@ResponseBody
public ResponseMessage unauthorized(Exception exception) {
LOGGER.warn(exception.getMessage(), exception);
LOGGER.info("catch UnknownAccountException");
return Result.error(exception.getMessage());
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(UnauthorizedException.class)
@ResponseBody
public ResponseMessage unauthorized1(UnauthorizedException exception) {
LOGGER.warn(exception.getMessage(), exception);
return Result.error( exception.getMessage());
}
}
3.启动项目测试一下,现在调用这个接口的话会抛出一个异常,说没有这个权限
4.这个时候我们需要在文章开头的那段代码中把这个权限加进去
/**
* 设置授权信息,目前这个方法没有什么作用
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
logger.info("开始授权(doGetAuthorizationInfo)");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//角色
// Set<String> roles = new HashSet<>();
// roles.add("role1");
// authorizationInfo.setRoles(roles);
//权限
Set<String> permissions = new HashSet<>();
permissions.add("user:list");
permissions.add("contacter:findByPage");
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
ps:我们这里为了测试是直接写在代码中的,实际项目中是将角色和权限的关系保存在数据库中,需要从数据库中查询出来的。
5.再次测试一下,结果如下:
测试成功!