zoukankan      html  css  js  c++  java
  • java微服务 Spring Security+oauth2 对form提交 鉴权

    场景:微服务系统中使用oauth2 的 Bearer 方式鉴权,对于from提交的数据,无法鉴权,百度的富文本编辑器 ueditor 中上传图片都是使用form 伪ajax提交,导致401

    因为from提交无法设置header

    解决方式:

    1、修改百度富文本编辑器的源码ueditor.all.min.js,在调用上传图片方法的时候,加入额外参数

    /**
             * 获取服务器提交的额外参数列表
             * @command serverparam
             * @method queryCommandValue
             * @param { String } cmd 命令字符串
             * @example
             * ```javascript
             * editor.queryCommandValue( 'serverparam' ); //返回对象 {'key': 'value'}
             * ```
             */
            'serverparam': {
              execCommand: function (cmd, key, value) {
                if (key === undefined || key === null) { //不传参数,清空列表
                  serverParam = {};
                } else if (utils.isString(key)) { //传入键值
                  if (value === undefined || value === null) {
                    delete serverParam[key];
                  } else {
                    serverParam[key] = value;
                  }
                } else if (utils.isObject(key)) { //传入对象,覆盖列表项
                  utils.extend(serverParam, key, true);
                } else if (utils.isFunction(key)) { //传入函数,添加列表项
                  utils.extend(serverParam, key(), true);
                }
    
              },
              queryCommandValue: function () {
                if(!serverParam){
                  serverParam={};
                }
            //修改的地方 var accessToken=JSON.parse(window.sessionStorage.getItem("pigx-access_token")).content; var token = accessToken || ''; serverParam['_authorization']= token; serverParam['_domain']= window.location.host; console.log(serverParam) return serverParam || {}; } }

     2、还有修改doAjax方法

    function doAjax(url, ajaxOptions) {
          var xhr = creatAjaxRequest(),
            //是否超时
            timeIsOut = false,
            //默认参数
            defaultAjaxOptions = {
              method: "POST",
              timeout: 5000,
              async: true,
              data: {},//需要传递对象的话只能覆盖
              onsuccess: function () {
              },
              onerror: function () {
              }
            };
    
          if (typeof url === "object") {
            ajaxOptions = url;
            url = ajaxOptions.url;
          }
          if (!xhr || !url) return;
          var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions, ajaxOptions) : defaultAjaxOptions;
    
          var submitStr = json2str(ajaxOpts);  // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing"
          //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串
          if (!utils.isEmptyObject(ajaxOpts.data)) {
            submitStr += (submitStr ? "&" : "") + json2str(ajaxOpts.data);
          }
          //超时检测
          var timerID = setTimeout(function () {
            if (xhr.readyState != 4) {
              timeIsOut = true;
              xhr.abort();
              clearTimeout(timerID);
            }
          }, ajaxOpts.timeout);
    
          var method = ajaxOpts.method.toUpperCase();
          var str = url + (url.indexOf("?") == -1 ? "?" : "&") + (method == "POST" ? "" : submitStr + "&noCache=" + +new Date);
          xhr.open(method, str, ajaxOpts.async);
          xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
              if (!timeIsOut && xhr.status == 200) {
                ajaxOpts.onsuccess(xhr);
              } else {
                ajaxOpts.onerror(xhr);
              }
            }
          };
        //修改的地方 var accessToken=JSON.parse(window.sessionStorage.getItem("pigx-access_token")).content; var token = accessToken || ''; xhr.setRequestHeader('Authorization', 'Bearer '+token); xhr.setRequestHeader('X-DOMAIN', window.location.host); if (method == "POST") { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(submitStr); } else { xhr.send(null); } }

     3、修改复制的图片自动上传的方法

    /**
       * @description
       * 1.拖放文件到编辑区域,自动上传并插入到选区
       * 2.插入粘贴板的图片,自动上传并插入到选区
       * @author Jinqn
       * @date 2013-10-14
       */
      UE.plugin.register('autoupload', function () {
    
        function sendAndInsertFile(file, editor) {
          var me = editor;
          //模拟数据
          var fieldName, urlPrefix, maxSize, allowFiles, actionUrl,
            loadingHtml, errorHandler, successHandler,
            filetype = /image/w+/i.test(file.type) ? 'image' : 'file',
            loadingId = 'loading_' + (+new Date()).toString(36);
    
          fieldName = me.getOpt(filetype + 'FieldName');
          urlPrefix = me.getOpt(filetype + 'UrlPrefix');
          maxSize = me.getOpt(filetype + 'MaxSize');
          allowFiles = me.getOpt(filetype + 'AllowFiles');
          actionUrl = me.getActionUrl(me.getOpt(filetype + 'ActionName'));
          errorHandler = function (title) {
            var loader = me.document.getElementById(loadingId);
            loader && domUtils.remove(loader);
            me.fireEvent('showmessage', {
              'id': loadingId,
              'content': title,
              'type': 'error',
              'timeout': 4000
            });
          };
    
          if (filetype == 'image') {
            loadingHtml = '<img class="loadingclass" id="' + loadingId + '" src="' +
              me.options.themePath + me.options.theme +
              '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >';
            successHandler = function (data) {
              var link = urlPrefix + data.url,
                loader = me.document.getElementById(loadingId);
              if (loader) {
                loader.setAttribute('src', link);
                loader.setAttribute('_src', link);
                loader.setAttribute('title', data.title || '');
                loader.setAttribute('alt', data.original || '');
                loader.removeAttribute('id');
                domUtils.removeClasses(loader, 'loadingclass');
              }
            };
          } else {
            loadingHtml = '<p>' +
              '<img class="loadingclass" id="' + loadingId + '" src="' +
              me.options.themePath + me.options.theme +
              '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >' +
              '</p>';
            successHandler = function (data) {
              var link = urlPrefix + data.url,
                loader = me.document.getElementById(loadingId);
    
              var rng = me.selection.getRange(),
                bk = rng.createBookmark();
              rng.selectNode(loader).select();
              me.execCommand('insertfile', {'url': link});
              rng.moveToBookmark(bk).select();
            };
          }
    
          /* 插入loading的占位符 */
          me.execCommand('inserthtml', loadingHtml);
    
          /* 判断后端配置是否没有加载成功 */
          if (!me.getOpt(filetype + 'ActionName')) {
            errorHandler(me.getLang('autoupload.errorLoadConfig'));
            return;
          }
          /* 判断文件大小是否超出限制 */
          if (file.size > maxSize) {
            errorHandler(me.getLang('autoupload.exceedSizeError'));
            return;
          }
          /* 判断文件格式是否超出允许 */
          var fileext = file.name ? file.name.substr(file.name.lastIndexOf('.')) : '';
          if ((fileext && filetype != 'image') || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
            errorHandler(me.getLang('autoupload.exceedTypeError'));
            return;
          }
    
          /* 创建Ajax并提交 */
          var xhr = new XMLHttpRequest(),
            fd = new FormData(),
            params = utils.serializeParam(me.queryCommandValue('serverparam')) || '',
            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?' : '&') + params);
    
          fd.append(fieldName, file, file.name || ('blob.' + file.type.substr('image/'.length)));
          fd.append('type', 'ajax');
          xhr.open("post", url, true);
          var accessToken=JSON.parse(window.sessionStorage.getItem("pigx-access_token")).content;
          var token = accessToken || '';
          xhr.setRequestHeader('Authorization', 'Bearer '+token);
          xhr.setRequestHeader('X-DOMAIN', window.location.host);
          xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
          xhr.addEventListener('load', function (e) {
            try {
              var json = (new Function("return " + utils.trim(e.target.response)))();
              if (json.state == 'SUCCESS' && json.url) {
                successHandler(json);
              } else {
                errorHandler(json.state);
              }
            } catch (er) {
              errorHandler(me.getLang('autoupload.loadError'));
            }
          });
          xhr.send(fd);
        }
    

      

    4、在后台的过滤器中进行处理,针对接收到的额外参数,

    @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //百度编辑器,上传图片时会使用form提交,无法设置header,so,修改如下代码
            if(((HttpServletRequest) request).getRequestURI().contains("ueditorConfig") && StringUtils.isNotBlank(request.getParameter("_authorization")))
            {
                HttpHeaderRequestWrapper httpHeaderRequestWrapper = new HttpHeaderRequestWrapper((HttpServletRequest) request
                        , request.getParameter("_authorization")
                        ,request.getParameter("_domain"));
                //this.setDomain(httpHeaderRequestWrapper, (HttpServletResponse) response);
                chain.doFilter(httpHeaderRequestWrapper, response);
            }
            else{
                //this.setDomain((HttpServletRequest)request,(HttpServletResponse)response);
                chain.doFilter(request,response);
            }
            //请求完成还原线程变量的值
            log.info("还原线程变量中的值");
            //HostThreadLocalConstant.getDomian().set("");
        }
    

      5、重写 getHeaders 方法

    private static class HttpHeaderRequestWrapper extends HttpServletRequestWrapper{
    
            private final String domain;
            private final String authorization;
    
            public HttpHeaderRequestWrapper(HttpServletRequest request,String authorization,String domain) {
                super(request);
                this.domain=domain;
                this.authorization="Bearer "+authorization;
            }
    
            @Override
            public String getHeader(String name) {
                if (name!=null &&
                        name.equals("X-DOMAIN") &&
                        super.getHeader("X-DOMAIN")==null) {
                    return domain;
                }else if (name!=null &&
                        name.equals("Authorization") &&
                        super.getHeader("Authorization")==null) {
                    return authorization;
                }else {
                    return super.getHeader(name);
                }
            }
    
            @Override
            public Enumeration<String> getHeaders(String name) {
                List<String> values = Collections.list(super.getHeaders(name));
                if (name!=null && name.equals("Authorization") ) {
                    values.add(authorization);
                }
                return Collections.enumeration(values);
            }
    
    
        }
    

      

  • 相关阅读:
    HomeWork2
    An error I have completed recently
    C#之规格说明书
    App上架审核指南翻译
    使用CollectionView做横向滑动分页效果:
    推荐一些CSS命名规范
    关于让左右2个DIV高度相等
    带有缩略图和文字提示的轮播图
    动画的定义:
    .Net基础篇_学习笔记_第五天_流程控制while循环002
  • 原文地址:https://www.cnblogs.com/forthelichking/p/11857843.html
Copyright © 2011-2022 走看看