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);
        }


    }

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM