6月28
今天在项目中发现一个问题:使用shiro的时候,虽然隐藏掉了一些菜单,但是当我们通过get请求直接访问菜单的时候还是会访问到,也就是shiro可以在界面实现隐藏一些信息,但是没有真正的根据权限码验证请求,于是想自己在后台实现验证。
需求:有权限(权限码是systemmanager:settings)的人可以点击系统设置跳转到系统设置页面,没权限的人看不到菜单,但是通过get访问可以访问到,于是需要在后台拦截。
实现思路:在需要精确验证的方法开始先验证权限,如果验证成功啥也不做,验证失败的话就抛出一个没有权限的异常。在拦截器中捕捉到异常就记录日志,并返回到提醒页面。
1. 验证Shiro权限的工具类(此工具还可以进一步完善,封装为判断是否有指定角色,或者有任意角色)
package com.microxiang.common.util;
import com.microxiang.common.constant.ResultCode;
import com.microxiang.common.exception.user.NoPermissionException;
import com.microxiang.common.system.vo.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
/**
* 验证shiro权限的工具类
*
* @author jiangjun
*/
@Slf4j
public class ShiroPermissionUtils {
private ShiroPermissionUtils() {
}
/**
* 检查当前用户是否有权限(任意一项)
*
* @param permissionCodes 任意权限
* @throws NoPermissionException
*/
public static void checkPermissionAny(String... permissionCodes) {
if (permissionCodes == null || permissionCodes.length == 0) {
return;
}
// 获取用户信息
Subject currentUser = SecurityUtils.getSubject();
for (String permission : permissionCodes) {
boolean permitted = currentUser.isPermitted(permission);// 判断是否有权限
if (permitted) {
return;
}
}
// 没权限就抛出一个异常
Object principal = currentUser.getPrincipal();
if (principal instanceof LoginUser) {
LoginUser user = (LoginUser) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("user no permission !");
}
/**
* 检查当前用户是否有权限(所有的)
*
* @param permissionCodes 任意权限
* @throws NoPermissionException
*/
public static void checkPermissionAll(String... permissionCodes) {
if (permissionCodes == null || permissionCodes.length == 0) {
return;
}
// 获取用户信息
Subject currentUser = SecurityUtils.getSubject();
for (String permission : permissionCodes) {
boolean permitted = currentUser.isPermitted(permission);// 判断是否有权限
if (!permitted) {
// 没权限就抛出一个异常
Object principal = currentUser.getPrincipal();
if (principal instanceof LoginUser) {
LoginUser user = (LoginUser) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("no permission ");
}
}
}
}
解释:
(1)Subject currentUser = SecurityUtils.getSubject(); 先获取到Subject,
(2)boolean permitted = currentUser.isPermitted(permission); 然后验证权限
(3)如果验证失败就记录日志,(获取到subject中的principal,principal其实是认证的时候装进SimpleAuthenticationInfo的user对象)
Object principal = currentUser.getPrincipal();
if (principal instanceof User) {
User user = (User) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("no permission ");
2.自定义异常(如果不自定义异常,也可以在程序中抛出一个运行时异常throw new RuntimeException("XXXXX");)
必须继承RuntimeException,运行时异常不需要在抛出异常的时候显示的捕捉或者声明(throws.....),如果继承Exception为检查异常,需要捕捉或者throws声明.
package com.microxiang.common.exception.user;
import com.microxiang.common.constant.ResultCode;
import com.microxiang.common.exception.BusinessException;
/**
* 没有权限异常
* Created by jiangjun on 2020/6/28 14:47
*/
public class NoPermissionException extends BusinessException {
public NoPermissionException() {
super(ResultCode.USER_NOT_AUTHORIZED);
}
public NoPermissionException(String message) {
super(ResultCode.USER_NOT_AUTHORIZED.getCode(), message);
}
public NoPermissionException(String message, Throwable cause) {
super(ResultCode.USER_NOT_AUTHORIZED.getCode(), message, cause);
}
}
至此,完成了后台验证,也就是在所有方法开始先验证权限。
还有另一种办法就是自定义注解实现权限验证,有点类似于shiro自带的注解验证权限,参
来源:Heck's Blog
地址:https://www.heckjj.com/post/507/
转载时须以链接形式注明作者和原始出处及本声明,否则将追究法律责任,谢谢配合!
需求:有权限(权限码是systemmanager:settings)的人可以点击系统设置跳转到系统设置页面,没权限的人看不到菜单,但是通过get访问可以访问到,于是需要在后台拦截。
实现思路:在需要精确验证的方法开始先验证权限,如果验证成功啥也不做,验证失败的话就抛出一个没有权限的异常。在拦截器中捕捉到异常就记录日志,并返回到提醒页面。
1. 验证Shiro权限的工具类(此工具还可以进一步完善,封装为判断是否有指定角色,或者有任意角色)
package com.microxiang.common.util;
import com.microxiang.common.constant.ResultCode;
import com.microxiang.common.exception.user.NoPermissionException;
import com.microxiang.common.system.vo.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
/**
* 验证shiro权限的工具类
*
* @author jiangjun
*/
@Slf4j
public class ShiroPermissionUtils {
private ShiroPermissionUtils() {
}
/**
* 检查当前用户是否有权限(任意一项)
*
* @param permissionCodes 任意权限
* @throws NoPermissionException
*/
public static void checkPermissionAny(String... permissionCodes) {
if (permissionCodes == null || permissionCodes.length == 0) {
return;
}
// 获取用户信息
Subject currentUser = SecurityUtils.getSubject();
for (String permission : permissionCodes) {
boolean permitted = currentUser.isPermitted(permission);// 判断是否有权限
if (permitted) {
return;
}
}
// 没权限就抛出一个异常
Object principal = currentUser.getPrincipal();
if (principal instanceof LoginUser) {
LoginUser user = (LoginUser) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("user no permission !");
}
/**
* 检查当前用户是否有权限(所有的)
*
* @param permissionCodes 任意权限
* @throws NoPermissionException
*/
public static void checkPermissionAll(String... permissionCodes) {
if (permissionCodes == null || permissionCodes.length == 0) {
return;
}
// 获取用户信息
Subject currentUser = SecurityUtils.getSubject();
for (String permission : permissionCodes) {
boolean permitted = currentUser.isPermitted(permission);// 判断是否有权限
if (!permitted) {
// 没权限就抛出一个异常
Object principal = currentUser.getPrincipal();
if (principal instanceof LoginUser) {
LoginUser user = (LoginUser) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("no permission ");
}
}
}
}
解释:
(1)Subject currentUser = SecurityUtils.getSubject(); 先获取到Subject,
(2)boolean permitted = currentUser.isPermitted(permission); 然后验证权限
(3)如果验证失败就记录日志,(获取到subject中的principal,principal其实是认证的时候装进SimpleAuthenticationInfo的user对象)
Object principal = currentUser.getPrincipal();
if (principal instanceof User) {
User user = (User) principal;
log.error("user {} no permission !", user.getUsername());
}
throw new NoPermissionException("no permission ");
2.自定义异常(如果不自定义异常,也可以在程序中抛出一个运行时异常throw new RuntimeException("XXXXX");)
必须继承RuntimeException,运行时异常不需要在抛出异常的时候显示的捕捉或者声明(throws.....),如果继承Exception为检查异常,需要捕捉或者throws声明.
package com.microxiang.common.exception.user;
import com.microxiang.common.constant.ResultCode;
import com.microxiang.common.exception.BusinessException;
/**
* 没有权限异常
* Created by jiangjun on 2020/6/28 14:47
*/
public class NoPermissionException extends BusinessException {
public NoPermissionException() {
super(ResultCode.USER_NOT_AUTHORIZED);
}
public NoPermissionException(String message) {
super(ResultCode.USER_NOT_AUTHORIZED.getCode(), message);
}
public NoPermissionException(String message, Throwable cause) {
super(ResultCode.USER_NOT_AUTHORIZED.getCode(), message, cause);
}
}
至此,完成了后台验证,也就是在所有方法开始先验证权限。
还有另一种办法就是自定义注解实现权限验证,有点类似于shiro自带的注解验证权限,参
来源:Heck's Blog
地址:https://www.heckjj.com/post/507/
转载时须以链接形式注明作者和原始出处及本声明,否则将追究法律责任,谢谢配合!
怎么能把微信/QQ昵称加
服务器反向代理静态资源出



