【常用功能】使用自定义注解完成URL鉴权功能

背景:用户有对应菜单的权限,但是如果用户知道了其他菜单的URL,直接访问URL的话,就可以访问用户本来并不
具有权限的菜单,所以为了避免这种越权访问现象,提出根据URL鉴权的功能。

一、新建自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MenuToUrl {

    //菜单id
    String menuId() default "";
    
    //访问URL
    String url() default "";

}

二、实现自定义注解信息收集

新建自定义类MyListenerProcessor,实现BeanPostProcessor接口,重写postProcessAfterInitialization方法。此方法会在所有bean加载完成后调成,可以在这里通过反射获取所有类中所有方法,在获取方法上的自定义注解信息,保存在一个全局变量 StoreMenuUrlMap

@Component
public class MyListenerProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(bean));
        if (methods != null) {
            for (Method method : methods) {
                MenuToUrl menuToUrl = method.getAnnotation(MenuToUrl.class);
                if(menuToUrl != null){
                    String[] menuIds = menuToUrl.menuId().split(",");
                    for(String menuId : menuIds){
                        StoreMenuUrlMap.getMenuUrlMap().put(menuId, menuToUrl.url());
                    }
                }
            }
        }
        return bean;
    }
}

备注: 在通过ReflectionUtils.getAllDeclaredMethods()获取所有方法是,如果注解的类在被代理的包中时,需要AopUtils.getTargetClass()通过代理类获取实际类,才能获取到所有方法。

三、监听器将自定义注解信息入库

新建InitMenuAndUrlListener,在项目启动时,将全局变量StoreMenuUrlMap中的数据持久化到数据库指定表中。

public class InitMenuAndUrlListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        DbUtil.update("delete from tab_menu_url");
        Map<String,String> menuUrlMap = StoreMenuUrlMap.getMenuUrlMap();
        String insertSql = "insert into tab_menu_url (menu_id,url) values ";
        StringBuilder sb = new StringBuilder();
        for(Map.Entry<String,String> entry : menuUrlMap.entrySet()){
            sb.append(",('").append(entry.getKey()).append("','").append(entry.getValue()).append("')");
        }
        DbUtil.update(insertSql + sb.substring(1));
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

四、拦截器完成URL鉴权功能

通过拦截器将所有请求进行拦截,通过项目启动时生成的表完成URL鉴权功能。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值