1、问题场景:
最近公司在研发一套新的项目,其中涉及到了用户查询端和管理员端(也就是后台),查询员有查询员的接口,管理员有管理员的接口,但是也有一些公共的接口,比如说文件上传,文件查看的接口。校验用户是否登录的条件是通过springSession完成的。
出现的问题就是在使用swagger接口进行测试的时候,发现查询员登录成功之后,也可以访问管理员的接口,这就出现了横向越权的问题。
2、解决思路:
- 刚开始的想法是各自添加标识,管理端的接口自定义一个注解,查询端的接口自定义一个注解,未添加注解的就是公共接口,但是这样的工作量太大了,也不符合Java开发的思想和开发规范。所以被pass掉了。
- 后来想到了由于查询端的接口和公共的接口较少,分别给他们俩添加注解,没添加注解的就是管理端的接口,这种方法其实和第一种不相上下,也被果断的pass掉了
- 再后来又想到了Spring Security框架,但现实的问题是,目前做的只是第一版,权限和角色并没有进行彻底的分离,所以若要使用Spring
Security框架的话,反而会把简单的问题复杂化,这种方式是目前不可取的,但是相比于上面的两种方法,在思想上已经进步了很多了(哈哈哈)- 最后想到了一种方法,也是最后采用的一种方法。
第一步:将查询端使用的接口全部放到一个Controller下面(因为查询端的接口较少),公共接口因为只有两个,所以就将它们进行了复制,管理端一份,查询端一份,其实他们service层是一模一样的。
第二步:在用户登录上之后,根据用户类型的不同在他们的cookie中分别种上不同的标识(我添加的是userType)
第三步:在这个查询端的Controller上面添加一个注解,在拦截器进行拦截,只要拦截到是添加这个注解的就是查询端的接口,没添加这个注解的就是管理端的接口,拦截到之后对cookie中的类型进行判断,判断类型是否合适,合适就通过,不合适就抛异常。
核心代码如下:
//获取类上的注解
CustomAuth customAuthAnnotation = method.getMethod().getDeclaringClass().getAnnotation(CustomAuth.class);
if (!sessionService.validUserType(customAuthAnnotation,request.getSession())){
throw new ErrorCodeException(ErrorCode.USER_AUTH_NOT_EXIST);
}
(全部的拦截器的代码在之前的博客中)
这是目前想到的最合适也是最便捷的方法,网友们有比较合适的思路欢迎评论留言!