美文网首页程序员日创创作
毕设(校园交流平台)权限修正

毕设(校园交流平台)权限修正

作者: 其实是白羊 | 来源:发表于2020-02-09 13:36 被阅读0次

前段时间把毕设部署到了线上,果然当时懒惰没认真做权限,部署完没多久就被大佬看破了然后

image

好吧然后我就趁今天有时间修复下。

先说下现状

当时为了懒省劲(大家别学我)只在user表上加了一个字段判断是否管理员身份,权限上只在部分接口上加了,现在想起来还真是漏洞百出。

其实就管理员和普通用户两种角色,但由于后端权限未做全导致现在存在的问题:

  • 管理员权限泄露
  • 普通用户存在数据权限越权危险

想怎么做

    1. 由于之前引入了shiro框架,针对用户角色的限制可已通过增加shiro中自定义Realm来实现(之前没写),然后在只能管理员调用的接口前增加相应的注解来实现。
    @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String userName = (String) principalCollection.getPrimaryPrincipal();
            User user = iservice.getUserByUserName(userName);
            if (user != null && user.getAdmin() != null && StringUtils.equals(user.getAdmin(), Constant.ROLE_ADMIN)) {
                SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
                authorizationInfo.addRole(Constant.ROLE_ADMIN);
                return authorizationInfo;
            }
            return null;
        }
    
    @RequiresRoles(Constant.ROLE_ADMIN)
    

    这里遇到了个问题:调用使用了@RequireRoles的接口时并未进入授权方法,解决办法:

    在spring-mvc注解中加入下面代码:

    <!--用来管理shiro一些bean的生命周期-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true" />
        </bean>
    
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
    
    1. 到这里如果被加上@RequireRoles的接口被访问时没相应的角色,会抛出UnauthorizedException异常,改到这里又发现还没做统一异常处理,这里稍微做个满足需求简单的:
    public class MyExceptionHandler implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
            ModelAndView modelAndView = new ModelAndView();
            Map<String, Object> result = new HashMap<>(4);
            if (e instanceof UnauthorizedException) {
                result.put("success", false);
                result.put("message", "抱歉您无此权限");
    
            }else {
                //这里应该使用统一返回数据格式,不应该每次都这样拼装
                result.put("success", false);
                result.put("message", "系统错误请联系管理员");
            }
            FastJsonJsonView view = new FastJsonJsonView();
            view.setAttributesMap(result);
            modelAndView.setView(view);
            return modelAndView;
        }
    }
    
    <!--统一异常处理-->
      <bean class="com.zll.ccp.config.MyExceptionHandler"/>
    
  • 针对普通用户只能操作自己的相关资源:

    1. 创建注解@RequireOwn并加在需要判断是否操作的是自己资源的接口上

      @Target({ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      public @interface RequireOwn {
          //资源类型
          ResourceType resourceType();
          
          //资源的唯一身份认证在参数的位置
          int keyIndexOf() default 0;
      }
      
    2. 然后编写intercepter在调用具体接口前通过反射查看相应的接口方法上是否有@RequireOwn注解,并判断身份是否符合。

    ```java 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
                RequireOwn requireOwn = method.getDeclaredAnnotation(RequireOwn.class);
    //            RequireOwn requireOwn = method.getAnnotation(RequireOwn.class);
                HttpSession session = request.getSession();
                if (requireOwn != null && !(boolean) session.getAttribute(Constant.ROLE_ADMIN)) {
                    //有注解且不是管理员则需要验明正身
                    //真正的身份
                    String userId = (String) session.getAttribute("userId");
                    String parameter = request.getParameter(requireOwn.paramName());
                    String userKey = getResourceOwnId(requireOwn, parameter);
                    if (!StringUtils.equals(userId, userKey)) {
                        throw new UnauthorizedException();
                    }
                }
            }
            return true;
        }
    /**
         * 根据注解提供的资源类型和获取到的参数获得该资源真正拥有者的身份id
         * @param requireOwn 注解类
         * @param key 资源id
         * @return
         */
        private String getResourceOwnId(RequireOwn requireOwn,String key) {
            String userKey="";
            ResourceType resourceType = requireOwn.resourceType();
            switch (resourceType) {
                case blog:
                    Blog blog = blogMapper.getBlogById(key);
                    if (blog!=null){
                        userKey = blog.getUserId();
                    }
                    break;
                case comment:
                    BlogComment blogCommentsId = blogCommentMapper.getBlogCommentsId(key);
                    if (blogCommentsId!=null) {
                        userKey = blogCommentsId.getUserId();
                    }
                    break;
                case reply:
                    BlogReply blogReplyByid = blogReplyMapper.getBlogReplyByid(key);
                    if (blogReplyByid != null) {
                        userKey = blogReplyByid.getFromUserId();
                    }
                    break;
                case theme:
                    Theme themeById = themeMapper.getThemeById(key);
                    if (themeById != null) {
                        userKey = themeById.getUserid();
                    }
                    break;
                case main:
                    MainPosts mainById = mainPostsMapper.getMainById(key);
                    if (mainById!=null) {
                        userKey=mainById.getUserid();
                    }
                    break;
                default:
                    MinorPosts minorById = minorPostsMapper.getMinorById(key);
                    if (minorById!=null) {
                        userKey=minorById.getUserid();
                    }
            }
            return userKey;
        }
    ```
    
    1. 对于一些如参数是json类型的由于数量很少就直接修改原来代码了。

至此完成了权限的修正

项目地址:校园交流平台

源码:ccp

欢迎star

相关文章

  • 毕设(校园交流平台)权限修正

    前段时间把毕设部署到了线上,果然当时懒惰没认真做权限,部署完没多久就被大佬看破了然后image好吧然后我就趁今天有...

  • 毕设毕设

    最近某些人又要被逼疯了。 因为一个两个字的东西,“毕设”,最近全宿舍都在每天做毕设,因为要交稿的日期将近。 每当截...

  • 毕设

    告别这美好的2个月 又让我重回大学时光

  • 毕设

    辛追穿着汉服,睡在河边,狼狈不堪。恰逢一个担着蔬菜的汉子(利仓穿越至现代的人),将他救起,他将她带到家里,照顾贴切...

  • 毕设

    2.毕业设计环节中的具体工作内容(包括原始数据、技术、工作要求等): 主要功能: 详细的礼物分类,解决送礼物难...

  • 毕设

    弹指一挥间,一周过去了。毕业设计也要接近最后的尾声,只剩下最后的毕业答辩。 过去人们常说:The knowledg...

  • 毕设

    这几天还在杭州 因为药面试 但是回来后 也考虑果毕设 之前问了哥哥 我做的这个系统要有传照片 穿视频等等 类似于Q...

  • 看到希望

    今天下午见了我的毕设导师,汇报了一下我的毕设进展。导师说后期着重于校园建筑的模型建立和基础设施的添加,之后再添加几...

  • 记录毕设

    终于完成查重啦,这里先竖面旗,找个机会把自己的毕设记录下,先吐槽一下毕设老师。在我毕设开始之前,从不知道一个毕设老...

  • 毕设答辩

    第六页 日常生活流程,icon,当中发现需求(拉下来。用虚线 第七页 总结目标。孤独,下分几条。 和动机。 第八页...

网友评论

    本文标题:毕设(校园交流平台)权限修正

    本文链接:https://www.haomeiwen.com/subject/clwgxhtx.html