OAuth单点登录

编辑
文档创建者:夏娃 (67727 )     浏览次数:3455次     编辑次数:5次     最近更新:doreen0813 于 2017-11-30     

目录:

1、OAuth单点登陆编辑

1.1 描述
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。oAuth是Open Authorization的简写。
1.2 OAuth单点登录原理
通过过滤器拦截请求,期间通过aouth的认证过程,拿到user,实现帆软的单点登录。
1.3 实现步骤
1.将以下4个jave(HttpUtil.java、myexporter.java、myfilter.java、SSLConnectionClient.java)文件编译为class文件后,放到FineBI对应工程路径下:\WebReport\WEB-INF\classes\com\fr
注:若FineBI对应工程路径下的WEB-INF文件夹中没有classes\com\fr该路径,自行新建该路径。
HttpUtil.java
package com.fr; import com.fr.third.org.hsqldb.lib.StringUtil; import javax.net.ssl.*; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; /**  * 进行http访问的基本类  */ public class HttpUtil {     private static final String DEFAULT_CHARSET = "UTF-8";     private static final String METHOD_POST = "POST";     private static final String METHOD_GET = "GET";     private static final int CONNECTTIMEOUT = 5000;     private static final int READTIMEOUT = 5000;     private static class DefaultTrustManager implements X509TrustManager {         public X509Certificate[] getAcceptedIssuers() {             return null;         }         @Override         public void checkClientTrusted(X509Certificate[] cert, String oauthType)                 throws java.security.cert.CertificateException {         }         @Override         public void checkServerTrusted(X509Certificate[] cert, String oauthType)                 throws java.security.cert.CertificateException {         }     }     private static HttpURLConnection getConnection(URL url, String method, String ctype)             throws IOException {         HttpURLConnection conn = null;         if ("https".equals(url.getProtocol())) {             SSLContext ctx = null;             try {                 ctx = SSLContext.getInstance("TLS");                 ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() },                         new SecureRandom());             } catch (Exception e) {                 throw new IOException(e);             }             HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();             connHttps.setSSLSocketFactory(ctx.getSocketFactory());             connHttps.setHostnameVerifier(new HostnameVerifier() {                 public boolean verify(String hostname, SSLSession session) {                     return true;// 默认都认证通过                 }             });             conn = connHttps;         } else {             conn = (HttpURLConnection) url.openConnection();         }         conn.setRequestMethod(method);         conn.setDoInput(true);         conn.setDoOutput(true);         conn.setRequestProperty("User-Agent", "quantangle-apiclient-java");         conn.setRequestProperty("Content-Type", ctype);         conn.setRequestProperty("Connection", "Keep-Alive");         return conn;     }     /**      * 通过get方法访问,默认编码为utf-8      *      * @param url 访问的url地址      * @param params 请求需要的参数      * @return 返回请求响应的数据      * @throws IOException      */     public static String doGet(String url, Map<String, String> params) throws IOException {         return doGet(url, params, DEFAULT_CHARSET);     }     /**      * 通过get方法访问      *      * @param url 访问的url地址      * @param params 请求需要的参数      * @param charset 字符编码      * @return 返回请求响应的数据      * @throws IOException      */     public static String doGet(String url, Map<String, String> params, String charset)             throws IOException {         if (StringUtil.isEmpty(url) || params == null) {             return null;         }         String response = "";         url += "?" + buildQuery(params, charset);         HttpURLConnection conn = null;         String ctype = "application/x-www-form-urlencoded;charset=" + charset;         conn = getConnection(new URL(url), METHOD_GET, ctype);         response = getResponseAsString(conn);         return response;     }     /**      *      * @param url api请求的权路径url地址      * @param params api请求的业务级参数      * @return      * @throws IOException      */     public static String doPost(String url, Map<String, String> params) throws IOException {         return doPost(url, params, CONNECTTIMEOUT, READTIMEOUT);     }     /**      *      * 通过post方法请求数据,默认字符编码为utf-8      *      * @param url 请求的url地址      * @param params 请求的参数      * @param connectTimeOut 请求连接过期时间      * @param readTimeOut 请求读取过期时间      * @return 请求响应      * @throws IOException      */     public static String doPost(String url, Map<String, String> params, int connectTimeOut,                                 int readTimeOut) throws IOException {         return doPost(url, params, DEFAULT_CHARSET, connectTimeOut, readTimeOut);     }     /**      *      * 通过post方法请求数据      *      * @param url 请求的url地址      * @param params 请求的参数      * @param charset 字符编码格式      * @param connectTimeOut 请求连接过期时间      * @param readTimeOut 请求读取过期时间      * @return 请求响应      * @throws IOException      */     public static String doPost(String url, Map<String, String> params, String charset,                                 int connectTimeOut, int readTimeOut) throws IOException {         HttpURLConnection conn = null;         String response = "";         String ctype = "application/x-www-form-urlencoded;charset=" + charset;         conn = getConnection(new URL(url), METHOD_POST, ctype);         conn.setConnectTimeout(connectTimeOut);         conn.setReadTimeout(readTimeOut);         conn.getOutputStream().write(buildQuery(params, charset).getBytes(charset));         response = getResponseAsString(conn);         return response;     }     /**      *      * @param params 请求参数      * @return 构建query      */     public static String buildQuery(Map<String, String> params, String charset) {         if (params == null || params.isEmpty()) {             return null;         }         StringBuilder sb = new StringBuilder();         boolean first = true;         for (Entry<String, String> entry : params.entrySet()) {             if (first) {                 first = false;             } else {                 sb.append("&");             }             String key = entry.getKey();             String value = entry.getValue();             if (!StringUtil.isEmpty(key) && !StringUtil.isEmpty(value)) {                 try {                     sb.append(key).append("=").append(URLEncoder.encode(value, charset));                 } catch (UnsupportedEncodingException e) {}             }         }         return sb.toString();     }     public static Map<String, String> splitQuery(String query, String charset) {         Map<String, String> ret = new HashMap<String, String>();         if (!StringUtil.isEmpty(query)) {             String[] splits = query.split("\\&");             for (String split : splits) {                 String[] keyAndValue = split.split("\\=");                 boolean flag=true;                 int i=0;int len=keyAndValue.length;                 for (;i<len;i++)                 {                     if (StringUtil.isEmpty(keyAndValue[i]))                     {                         flag=false;                         break;                     }                 }                 if (flag && keyAndValue.length == 2) {                     try {                         ret.put(keyAndValue[0], URLDecoder.decode(keyAndValue[1], charset));                     } catch (UnsupportedEncodingException e) {}                 }             }         }         return ret;     }     private static byte[] getTextEntry(String fieldName, String fieldValue, String charset)             throws IOException {         StringBuilder entry = new StringBuilder();         entry.append("Content-Disposition:form-data;name=\"");         entry.append(fieldName);         entry.append("\"\r\nContent-Type:text/plain\r\n\r\n");         entry.append(fieldValue);         return entry.toString().getBytes(charset);     }     private static byte[] getFileEntry(String fieldName, String fileName, String mimeType,                                        String charset) throws IOException {         StringBuilder entry = new StringBuilder();         entry.append("Content-Disposition:form-data;name=\"");         entry.append(fieldName);         entry.append("\";filename=\"");         entry.append(fileName);         entry.append("\"\r\nContent-Type:");         entry.append(mimeType);         entry.append("\r\n\r\n");         return entry.toString().getBytes(charset);     }     private static String getResponseAsString(HttpURLConnection conn) throws IOException {         String charset = getResponseCharset(conn.getContentType());         InputStream es = conn.getErrorStream();         if (es == null) {             return getStreamAsString(conn.getInputStream(), charset);         } else {             String msg = getStreamAsString(es, charset);             if (StringUtil.isEmpty(msg)) {                 throw new IOException("{\"" + conn.getResponseCode() + "\":\"" + conn.getResponseMessage() + "\"}");             } else {                 throw new IOException(msg);             }         }     }     private static String getStreamAsString(InputStream input, String charset) throws IOException {         StringBuilder sb = new StringBuilder();         BufferedReader bf = null;         try {             bf = new BufferedReader(new InputStreamReader(input, charset));             String str;             while ((str = bf.readLine()) != null) {                 sb.append(str);             }             return sb.toString();         } finally {             if (bf != null) {                 bf.close();                 bf = null;             }         }     }     private static String getResponseCharset(String ctype) {         String charset = DEFAULT_CHARSET;         if (!StringUtil.isEmpty(ctype)) {             String[] params = ctype.split("\\;");             for (String param : params) {                 param = param.trim();                 if (param.startsWith("charset")) {                     String[] pair = param.split("\\=");                     if (pair.length == 2) {                         charset = pair[1].trim();                     }                 }             }         }         return charset;     } } 
myexporter.java
package com.fr; import com.fr.base.DynamicUnitList; import com.fr.base.FRContext; import com.fr.base.ResultFormula; import com.fr.general.ComparatorUtils; import com.fr.general.DeclareRecordType; import com.fr.general.ModuleContext; import com.fr.general.web.ParameterConsts; import com.fr.io.TemplateWorkBookIO; import com.fr.io.exporter.AppExporter; import com.fr.io.exporter.PDFExporter; import com.fr.io.exporter.WordExporter; import com.fr.json.JSONArray; import com.fr.json.JSONException; import com.fr.json.JSONObject; import com.fr.main.TemplateWorkBook; import com.fr.main.workbook.ResultWorkBook; import com.fr.page.PageSetProvider; import com.fr.page.PaperSettingProvider; import com.fr.report.cell.CellElement; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.ResultCellElement; import com.fr.report.cell.cellattr.PageExportCellElement; import com.fr.report.core.ReportUtils; import com.fr.report.core.block.PolyResultWorkSheet; import com.fr.report.module.EngineModule; import com.fr.report.worksheet.PageRWorkSheet; import com.fr.stable.CodeUtils; import com.fr.stable.ColumnRow; import com.fr.stable.PageActor; import com.fr.stable.unit.FU; import com.fr.stable.unit.UNIT; import com.fr.web.Browser; import com.fr.web.core.ErrorHandlerHelper; import com.fr.web.core.utils.ExportUtils; import com.fr.web.utils.WebUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class myexporter  extends HttpServlet {     private static boolean offlineWriteAble = true;     private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("[^{,}]*:[^{,}]*");     public static void dealResponse4Export(HttpServletResponse res) {         res.setHeader("Cache-Control", "public");         res.setHeader("Cache-Control", "max-age=3");         res.reset();     }         private static final long serialVersionUID = 1L;         public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {             doGet(request, response);         }         public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {             // 首先需要定义执行所在的环境,这样才能正确读取数据库信息             try {                 ModuleContext.startModule(EngineModule.class.getName());                 dealResponse4Export(res);                 String fileName = WebUtils.getHTTPRequestParameter(req, ParameterConsts.__FILENAME__);                 String format = WebUtils.getHTTPRequestParameter(req, "format");                 Browser browser = Browser.resolve(req);                 fileName = browser.getEncodedFileName4Download(fileName);                 List paraMapList = new ArrayList();                 List reportPathList = new ArrayList();                 PaperSettingProvider paperSettingProvider=null;                 if (WebUtils.getHTTPRequestParameter(req, ParameterConsts.REPORTLETS) != null) {                     createReportsFromReportlets(WebUtils.getHTTPRequestParameter(req, ParameterConsts.REPORTLETS), reportPathList, paraMapList);                     ResultWorkBook[] resultWorkBook = new ResultWorkBook[reportPathList.size()];                     PolyResultWorkSheet allInOneSheet = new PageRWorkSheet();                     for (int i = 0; i < reportPathList.size(); i++) {                         TemplateWorkBook workbook = TemplateWorkBookIO.readTemplateWorkBook(FRContext.getCurrentEnv(), String.valueOf(reportPathList.get(i)));                         java.util.Map paraMap = (Map) paraMapList.get(i);                         resultWorkBook[i] = workbook.execute(paraMap, new PageActor());                         if (i==0)                         {                             paperSettingProvider=ReportUtils.getPaperSettingListFromWorkBook(workbook).get(0);                         }                     }                         int countx; int county; int length = resultWorkBook.length;                         long sumx;long sumy;                          long[] lengthx = new long[length];long[] lengthy = lengthx.clone();                         if (length > 0) {                             lengthx[0] = lengthy[0] = 0;                         }                         for (int i = 1; i < length; i++) {                              sumy = 0;                             county = resultWorkBook[i - 1].getElementCaseReport(0).getRowCount();                             while (county-- > 0) {                                 sumy = sumy + resultWorkBook[i - 1].getElementCaseReport(0).getRowHeight(county).getLen();                             }                             lengthx[i] = 0;lengthy[i] = sumy+lengthy[i-1];                         }                         ArrayList<UNIT> verticalList = new ArrayList<UNIT>();                         ArrayList<UNIT> horizontalList = new ArrayList<UNIT>();                         analyElementColumnRow(verticalList, horizontalList, resultWorkBook, lengthx, lengthy);                         allInOneSheet = setNewColRowSize(verticalList, horizontalList, allInOneSheet);                         //填充空白单元格                         allInOneSheet = fillBlankCell(verticalList.size(), horizontalList.size(), allInOneSheet);                         for (int i = 0, len = reportPathList.size(); i < len; i++) {                             //添加当前元素到新sheet中去                             allInOneSheet = addElemToSheet(verticalList, horizontalList, allInOneSheet, resultWorkBook[i], lengthx[i], lengthy[i]);                         }                     if (paperSettingProvider==null)                     {                         return;                     }                         // 将结果工作薄导出为Excel文件                     doExport(req, res, format, fileName,false, browser,allInOneSheet.generateReportPageSet(paperSettingProvider));                     }             }catch(Exception e){                     e.printStackTrace();                 }             }     private static void doExport(HttpServletRequest req, HttpServletResponse res,String format, String fileName, boolean isEmbbed, Browser browser,PageSetProvider page) throws Exception {         AppExporter[] exporters = new AppExporter[] {null};         DeclareRecordType[] exportTypes = new DeclareRecordType[] {null};         OutputStream outputStream = res.getOutputStream();         getExporterAndTypeAndexport(req, res, format, fileName, isEmbbed, browser, exporters,exportTypes,outputStream,page);         DeclareRecordType exportType = exportTypes[0];         if (exportType == null) {             ErrorHandlerHelper.getErrorHandler().error(req, res, "Cannot recognize the specifed export format:" + format + ",\nThe correct format can be PDF,Excel,Word,SVG,CSV,Text or Image.");             return;         }         try {             outputStream.flush();             outputStream.close();         } catch (IOException e) {             // alex:有些Exporter在export里面可能会已经做了out.close操作,为了不打印IOException,这里catch到之后不输出         }     }     private static void getExporterAndTypeAndexport(HttpServletRequest req, HttpServletResponse res,                                            String format, String fileName, boolean isEmbbed, Browser browser, AppExporter[] exporters, DeclareRecordType[] exportTypes,OutputStream out,PageSetProvider page) throws Exception{         if (format.equalsIgnoreCase("PDF")) {             ExportUtils.setPDFContent(res, fileName, isEmbbed);             PDFExporter PDFExport = new  PDFExporter();             PDFExport.export(out, page);         } else if (format.equalsIgnoreCase("Word")) {             ExportUtils.setWordConetent(res, fileName);             WordExporter WordExport = new WordExporter();             WordExport.export(out, page);         }     } //    private static AppExporter getPDFExporter(HttpServletRequest req, ReportSessionIDInfor sessionIDInfor) { //        AppExporter exporter; //        String extype = WebUtils.getHTTPRequestParameter(req, "extype"); //        // james:是否是PDF客户端打印 //        boolean isPDFPrint = ComparatorUtils.equals(WebUtils.getHTTPRequestParameter(req, "isPDFPrint"), "true"); //        // 标志是否正在为客户端PDF打印而生成PDF文件 //        // 打印的话,记录下 //        if (isPDFPrint) { //            LogUtils.recordPrintInfo(sessionIDInfor.getBookPath(), sessionIDInfor.getParameterMap4Execute4Consisent(), //                    DeclareRecordType.PRINT_TYPE_PDF, sessionIDInfor); //            if (!Browser.resolve(req).isIE()) { //                FRContext.getLogger().error(Inter.getLocText("NS_print_pdf")); //            } //        } // /* // * 根据sessionIDInfor获取当前的打印机偏移量,若为打印则设置偏移导出则不偏移 // */ //        SetPrinterOffsetService setprinteroffsetservice = new SetPrinterOffsetService(); //        float[] offset = setprinteroffsetservice.getOffsetBySessionIDInfor(sessionIDInfor); //        sessionIDInfor.setoffset(isPDFPrint ? offset : new float[2]); //        // carl:两种类型 //        if (ComparatorUtils.equals(ExportConstants.TYPE_RESOLVESOMETHING, extype)) { //            exporter = new PDFExporter2(isPDFPrint); //        } else { //            exporter = new PDFExporter(isPDFPrint); //        } //        return exporter; //    } // //    private static void dealExcelExporter(HttpServletRequest req, HttpServletResponse res, ReportSessionIDInfor sessionIDInfor, //                                          AppExporter[] exporters, DeclareRecordType[] exportTypes, String fileName, Browser browser) { //        // carl:四种输出方式 //        String extype = WebUtils.getHTTPRequestParameter(req, "extype"); //        // 假如是层式报表默认使用大数据方式 //        ResultWorkBook wb = sessionIDInfor.getWorkBook2Show(); //        boolean isPage = true; // 大数据量的时候要不要分页 //        for (int i = 0; i < wb.getReportCount(); i++) { //            if (wb.getReport(i) instanceof LayerReport || wb.getReport(i) instanceof LayerPageReport) { //                if (ExportConstants.TYPE_SIMPLE.equalsIgnoreCase(extype)) { //                    isPage = false; //                } //                if (!ExportConstants.TYPE_PAGETOSHETT.equalsIgnoreCase(extype)) { //                    extype = ExportConstants.TYPE_LARGEDATA_PAGE; //                } //                break; //            } //        } // //        if (ExportConstants.TYPE_LARGEDATA_PAGE.equalsIgnoreCase(extype)) { //            ExportUtils.setZipContext(res, fileName, browser.shouldSetContentTypeOnZipDownload()); //            exporters[0] = new LargeDataPageExcelExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook()), isPage); //            exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCEL_LARGE; //        } else { //            if (ExcelUtils.checkPOIJarExist() && !WebUtils.getHTTPRequestBoolParameter(req, "isExcel2003")) { //                ExportUtils.setExcel2007Content(res, fileName); //            } else { //                ExportUtils.setExcelContent(res, fileName); //            } // //            if (ExportConstants.TYPE_SIMPLE.equalsIgnoreCase(extype)) { //                exporters[0] = new ExcelExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())); //                exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCEL_ORIGINAL; //            } else if (ExportConstants.TYPE_PAGETOSHETT.equalsIgnoreCase(extype)) { //                exporters[0] = new PageToSheetExcelExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())); //                exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCEL_PAGESHEET; //            } else if (ExportConstants.TYPE_STREAM.equalsIgnoreCase(extype)) { //                exporters[0] = new StreamExcelExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())); //                exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCEL_ORIGINAL; //            } else { //                exporters[0] = new PageExcelExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())); //                exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCEL_PAGE; //            } // //            ((ExcelExporter)exporters[0]).setExcel2003(WebUtils.getHTTPRequestBoolParameter(req, "isExcel2003")); //        } //    } // //    private static DeclareRecordType getImageExportType(HttpServletRequest req) { //        DeclareRecordType[] supportImageType = {DeclareRecordType.EXPORT_TYPE_IMAGE_PNG, DeclareRecordType.EXPORT_TYPE_IMAGE_JPG, //                DeclareRecordType.EXPORT_TYPE_IMAGE_GIF, DeclareRecordType.EXPORT_TYPE_IMAGE_BMP, DeclareRecordType.EXPORT_TYPE_IMAGE_WBMP //        }; //        String extype = WebUtils.getHTTPRequestParameter(req, "extype"); //        int defaulttype = 0; //        if (extype != null) { //            for (int i = 0; i < supportImageType.length; i++) { //                if (extype.equalsIgnoreCase(supportImageType[i].getTypeString())) { //                    defaulttype = i; //                    break; //                } //            } //        } //        return supportImageType[defaulttype]; //    }     public static PolyResultWorkSheet fillBlankCell(int rowCount, int colCount,PolyResultWorkSheet allInOneSheet ){         for (int i = 0; i < rowCount; i++) {             for (int j = 0; j < colCount; j++) {                 //填充空白格, 主要是为了方便后续分页取cell iterator.next方便, 不然是null就不往下走了                 ResultCellElement ce = createDefaultCellElement(j, i);                 allInOneSheet.addCellElement(ce);             }         }         allInOneSheet.setRowMappingArray(new int[0]);         allInOneSheet.setColumnMappingArray(new int[0]);         return  allInOneSheet;     }     public static ResultCellElement createDefaultCellElement(int col, int row){         return new PageExportCellElement(new DefaultTemplateCellElement(col, row));     }     public  static  PolyResultWorkSheet addElemToSheet(ArrayList<UNIT> verticalList, ArrayList<UNIT> horizontalList, PolyResultWorkSheet page_sheet, ResultWorkBook  resultWorkBook,long lengthx,long lengthy){         UNIT x= FU.getInstance(lengthx);         UNIT y= FU.getInstance(lengthy);         DynamicUnitList newRowList = page_sheet.getRowHeightList_DEC();         DynamicUnitList newColList = page_sheet.getColumnWidthList_DEC();         int rowCount = page_sheet.getRowCount();         int colCount = page_sheet.getColumnCount();         DynamicUnitList rowHeightList = resultWorkBook.getElementCaseReport(0).getRowHeightList_DEC();         DynamicUnitList colWidthList = resultWorkBook.getElementCaseReport(0).getColumnWidthList_DEC();         Iterator<CellElement> it =  resultWorkBook.getElementCaseReport(0).cellIterator();         HashMap<String, String> columnRowMap = new HashMap<String, String>();         HashMap<CellElement, ResultFormula> formulaMap = new HashMap<CellElement, ResultFormula>();         while(it.hasNext()){             CellElement ce = it.next();             UNIT ceX = x.add(colWidthList.getRangeValueFromZero(ce.getColumn()));             UNIT ceWidth = colWidthList.getRangeValue(ce.getColumn(), ce.getColumn() + ce.getColumnSpan());             UNIT ceY = y.add(rowHeightList.getRangeValueFromZero(ce.getRow()));             UNIT ceHeight = rowHeightList.getRangeValue(ce.getRow(), ce.getRow() + ce.getRowSpan());             //直接去坐标列表里找, 然后+1, 因为行高list就是根据坐标列表生成的.             int newCeCol = horizontalList.indexOf(ceX) + 1;             int newCeColSpan = getNewSpan(newCeCol, newColList, ceWidth, colCount);             int newCeRow = verticalList.indexOf(ceY) + 1;             int newCeRowSpan = getNewSpan(newCeRow, newRowList, ceHeight, rowCount);             ColumnRow oriCR = ColumnRow.valueOf(ce.getColumn(), ce.getRow());             ColumnRow newCR = ColumnRow.valueOf(newCeCol, newCeRow);             //记录下格子的变迁, A1->B5, 这样后续公式有用到A1的都改成B5             columnRowMap.put(oriCR.toString(), newCR.toString());             ResultCellElement newCe = (ResultCellElement) ce.deriveCellElement(newCeCol, newCeRow, newCeColSpan, newCeRowSpan);             page_sheet.addCellElement(newCe);             if(ce.getValue() instanceof ResultFormula){                 formulaMap.put(newCe, (ResultFormula) ce.getValue());             }         }         //改变所有保留公式里的ColumnRow         modifyAllFormula(formulaMap, columnRowMap);         return page_sheet;     }     public static int getNewSpan(int newCeColRow, DynamicUnitList newColRowList, UNIT ceWidthHeight, int count){         for (int i = newCeColRow; i < count + 1; i++) {             if(ComparatorUtils.equals(ceWidthHeight, newColRowList.getRangeValue(newCeColRow, i))){                 return i - newCeColRow;             }         }         return 0;     }     public static     PolyResultWorkSheet setNewColRowSize(ArrayList<UNIT> verticalList, ArrayList<UNIT> horizontalList,    PolyResultWorkSheet allInOneSheet){         //从坐标列表里生成行高列宽 [0, 2, 6] -> [2, 4]         for (int i = 0; i < verticalList.size(); i++) {             UNIT lastCoordinate = i == 0 ? UNIT.ZERO : verticalList.get(i - 1);             UNIT rowHeight = verticalList.get(i).subtract(lastCoordinate);             allInOneSheet.setRowHeight(i, rowHeight);         }         for (int i = 0; i < horizontalList.size(); i++) {             UNIT lastCoordinate = i == 0 ? UNIT.ZERO : horizontalList.get(i - 1);             UNIT colWidth = horizontalList.get(i).subtract(lastCoordinate);             allInOneSheet.setColumnWidth(i, colWidth);         }         return allInOneSheet;     }     public static void analyElementColumnRow(ArrayList<UNIT> verticalList, ArrayList<UNIT> horizontalList,                                              ResultWorkBook [] resultWorkBooks,long [] lengthx,long [] lengthy){         int length=resultWorkBooks.length;         for (int i=0;i<length;i++) {             ResultWorkBook resultWorkBook = resultWorkBooks[i];             UNIT y =  FU.getInstance(lengthy[i]);             int rowCount = resultWorkBook.getElementCaseReport(0).getRowCount();             DynamicUnitList rowHeightList = resultWorkBook.getElementCaseReport(0).getRowHeightList_DEC();             analyColumnRow(y, verticalList, rowHeightList, rowCount);             //列处理             UNIT x = FU.getInstance(lengthx[i]);             int colCount = resultWorkBook.getElementCaseReport(0).getColumnCount();             DynamicUnitList colWidthList = resultWorkBook.getElementCaseReport(0).getColumnWidthList_DEC();             analyColumnRow(x, horizontalList, colWidthList, colCount);             //得到的多个块, 需要按序排列下, 才好切行高         }         sort(verticalList, horizontalList);     }     public  static void analyColumnRow(UNIT startPoint, ArrayList<UNIT> verticalSet,                                        DynamicUnitList rowHeightList, int count){         verticalSet.add(startPoint);         for (int i = 0; i < count; i++) {             UNIT rowHeight = rowHeightList.getRangeValueFromZero(i + 1);             UNIT rowY = rowHeight.add(startPoint);             verticalSet.add(rowY);         }     }     public  static  void sort(ArrayList<UNIT> verticalList, ArrayList<UNIT> horizontalList){         Comparator<UNIT> compare = new Comparator<UNIT>() {             public int compare(UNIT o1, UNIT o2) {                 if (o1.subtract(o2).equal_zero()){                     return 0;                 }                 return o1.subtract(o2).more_than_zero() ? 1 : -1;             };         };         Collections.sort(verticalList, compare);         Collections.sort(horizontalList, compare);     }     private static void modifyAllFormula(HashMap<CellElement, ResultFormula> formulaMap, HashMap<String, String> columnRowMap){         Iterator<Map.Entry<CellElement, ResultFormula>> formulaIt = formulaMap.entrySet().iterator();         while(formulaIt.hasNext()){             Map.Entry<CellElement, ResultFormula> entry = formulaIt.next();             CellElement ce = entry.getKey();             ResultFormula formula = entry.getValue();             String content = formula.getTransferContent();             Iterator<Map.Entry<String, String>> crIt = columnRowMap.entrySet().iterator();             while(crIt.hasNext()){                 Map.Entry<String, String> crEntry = crIt.next();                 String oriCR = crEntry.getKey();                 String newCR = crEntry.getValue();                 if(content.indexOf(oriCR) != -1){                     content = getNewFormula(content, oriCR, newCR);                     formula.setTransferContent(content);                     ce.setValue(formula);                 }             }         }     }     public static String getNewFormula(String formulaContent, String oriCR, String newCR){         String[] array = formulaContent.toUpperCase().split(oriCR);         StringBuffer sb = new StringBuffer();         for(int i = 0, len = array.length; i < len; i++){             sb.append(array[i]);             //=B1+A1             if(!formulaContent.endsWith(oriCR) && i == len - 1){                 continue;             }             //获取新值, 有的情况不需要替换             String nodeCR = getNewColumnRow(array[i], i + 1, array, oriCR, newCR);             sb.append(nodeCR);         }         return sb.toString();     }     private static String getNewColumnRow(String formulaPart, int nextIdx, String[] array, String oriCR, String newCR){         //如果是$p1这种就不认为他是一个单元格P1         if(formulaPart.endsWith("$")){             return oriCR;         }         //A11, 就不能只替换里面的A1, 而是要替换A11         if(nextIdx < array.length && startsWithDigit(array[nextIdx])){             return oriCR;         }         return newCR;     }     private static boolean startsWithDigit(String s) {         return Pattern.compile("^[0-9]").matcher(s.trim()).find();     }     public static String transferReportletsInfo(String reportletsInfo) {         try {             reportletsInfo = CodeUtils.cjkDecode(reportletsInfo.trim()); // bug40005:doURLPDFPrint打印会有编码问题         } catch (Exception e ){         }         // carl:这里兼容6.2原来的转换字符串的做法,原来的做法把所有值都变成了字符串,不好。所有现在让用户自己去写json         String jsonString = null;         if (reportletsInfo.length() > 0 && reportletsInfo.charAt(0) == '(') {             jsonString = transferToJSONString(reportletsInfo);         } else {             jsonString = reportletsInfo;         }         return jsonString;     }     /**      * carl:这里的转换器是大可不必,但一是考虑和6.2兼容,二是考虑可让用户方便一些      * @param reportletsInfo reportlets参数      * @return 转化后的JSONString形式的      */     public static String transferToJSONString(String reportletsInfo) {         if (reportletsInfo == null) {             return null;         }         reportletsInfo = reportletsInfo.trim();         if (reportletsInfo.length() <= 0) {             return null;         }         //james:去掉左右的括号,换成[]         reportletsInfo = reportletsInfo.substring(1, reportletsInfo.length() - 1);         //处理传过来的"{key:value,key:value...},{}..."字符串,让JSON能够解析         //开始的[         StringBuffer rpSB = new StringBuffer("[");         Matcher matcher = KEY_VALUE_PATTERN.matcher(reportletsInfo);         int start = 0;         int end = 0;         while (matcher.find()) {             //将不符合的部分先加进去             end = matcher.start();             String tmpText = reportletsInfo.substring(start, end);             if (tmpText != null && tmpText.length() > 0) {                 rpSB.append(tmpText);             }             start = matcher.end();             //             String tmpStr = matcher.group(); // System.out.println(tmpStr);             String[] tmpStrs = tmpStr.split(":");//参数key和value             if (tmpStrs.length != 2) {                 rpSB.append(tmpStr);             } else {                 rpSB.append(tmpStrs[0]).append(':').append(JSONObject.quote(tmpStrs[1]));//加上引号             }         }         //剩下的字符串         rpSB.append(reportletsInfo.substring(start, reportletsInfo.length()));         //还需要一个]哦         rpSB.append(']'); // System.out.println("reportlets:" + rpSB.toString());         return rpSB.toString();     }         public static void createReportsFromReportlets(String reportletsInfo, List reportPathList,                                                        List paraMapList) {             //先清空             reportPathList.clear();             paraMapList.clear();             if (reportletsInfo == null) {                 return;             }             String jsonString = transferReportletsInfo(reportletsInfo);             //打印处理结果,方便调试             FRContext.getLogger().info("reportletsInfo:" + jsonString);             if (jsonString == null) {                 return;             }             createFromReportlets(jsonString, reportPathList, paraMapList);         }         private static void createFromReportlets(String jsonString, List reportPathList,                                                  List paraMapList) {             try {                 JSONArray reportlets = new JSONArray(jsonString);                 String reportletPath;                 for (int i = 0; i < reportlets.length(); i++) {                     Map paraMap = new HashMap();                     JSONObject jsonObject = reportlets.getJSONObject(i);                     Iterator keys = jsonObject.keys();                     while (keys.hasNext()) {                         String key = (String) keys.next();                         Object value = jsonObject.get(key);                         value = (value instanceof String) ? CodeUtils.decodeText(String.valueOf(value)) : value;                         paraMap.put(key, value);                     }                     reportletPath = (String) paraMap.get("reportlet");                     if (reportletPath == null) {                         continue;                     } else {                         try {                             reportPathList.add(reportletPath);                             paraMapList.add(paraMap);                         } catch (Exception e) {                             FRContext.getLogger().error(e.getMessage(), e);                         }                     }                 }             } catch (JSONException e) {                 FRContext.getLogger().error(e.getMessage(), e);             }         } } 
myfilter.java
package com.fr; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.oltu.oauth2.client.OAuthClient; import org.apache.oltu.oauth2.client.request.OAuthClientRequest; import org.apache.oltu.oauth2.client.response.OAuthAuthzResponse; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.types.GrantType; import com.fr.fs.base.entity.User; import com.fr.fs.base.entity.UserInfo; import com.fr.fs.control.UserControl; import com.fr.fs.privilege.auth.FSAuthentication; import com.fr.fs.privilege.base.FServicePrivilegeLoader; import com.fr.fs.privilege.entity.DaoFSAuthentication; import com.fr.json.JSONException; import com.fr.json.JSONObject; import com.fr.privilege.session.PrivilegeInfoSessionMananger; import com.fr.stable.StringUtils; import com.fr.web.utils.WebUtils; public class myfilter implements Filter {     public void init(FilterConfig filterConfig) throws ServletException {     }     public void doFilter(ServletRequest request, ServletResponse response,                         FilterChain filterChain) throws IOException, ServletException {         HttpServletRequest req = (HttpServletRequest) request;         HttpServletResponse resp = (HttpServletResponse) response;         OAuthAuthzResponse oAuthResponse = null;         HttpSession session = req.getSession(true);         String tokenLocation="https:/www.example.com/oauth/token"; //请求token的地址         String redirectURI = "http://ip:端口号WebReport/ReportServer?op=fs" ; //授权后要回调的URI,当前系统通过此地址来获取Code需要回调的FineBI地址         String clientId= "xxxxx"; //在OAuth注册应用时获得的API Key         String clientSecret = "xxxxx" ; //在OAuth注册应用时获得的SecretKey                  String code = WebUtils.getHTTPRequestParameter(req, "code");                  try {                   if (!StringUtils.isEmpty(code))             {             oAuthResponse = OAuthAuthzResponse.oauthCodeAuthzResponse(req);             OAuthClientRequest oAuthClientRequest = OAuthClientRequest.tokenLocation(tokenLocation).setGrantType(GrantType.AUTHORIZATION_CODE).setClientId(clientId).setClientSecret(clientSecret).setRedirectURI(redirectURI).setCode(oAuthResponse.getCode()).buildBodyMessage();             OAuthClient oAuthClient = new OAuthClient(new SSLConnectionClient());              String  Token=oAuthClient.accessToken(oAuthClientRequest).getAccessToken();             System.out.println("Token" + Token);             Map<String, String> map =new HashMap<String, String>();             map.put("access_token",Token);             String res=HttpUtil.doPost("https://oauth.shu.edu.cn/rest/user/getLoggedInUser", map);             String username="";             if (!StringUtils.isEmpty(res))             {                 JSONObject resob=new JSONObject(res);                 username=resob.getString("userid");                 System.out.println("username"+username);             }             if (!StringUtils.isEmpty(username))             {                 //认证代码               User U = UserControl                          .getInstance().getByUserName(username);//根据当前用户名获取到fs里面对应的user对象,这个函数是封装好的,所以不用考虑健壮性                  if (U != null)                  {//System.out.println("username  is "+username);                  FSAuthentication authentication = new DaoFSAuthentication(new UserInfo(U.getId(), username, username));//根据user获取到fr的认证对象                  long userid = authentication.getUserInfo().getId();//获取当前用户id                  PrivilegeInfoSessionMananger.login(new FServicePrivilegeLoader(username, UserControl.getInstance().getAllSRoleNames(userid), UserControl.getInstance().getUserDP(userid)), session, resp);//登录认证,封装好的,不用考虑健壮性                  session.setAttribute("fr_fs_auth_key", authentication);//往session里面添加用户,避免二次认证                  UserControl.getInstance().login(userid);//登录相关。                  }                               }else             {                 //报错处理             }             }             filterChain.doFilter(req, resp);             } catch (OAuthProblemException e) {             e.printStackTrace();         } catch (OAuthSystemException e) {             e.printStackTrace();         } catch (JSONException e) {             e.printStackTrace();         } catch (Exception e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }     }     public void destroy() {     } } 
注:myfilter.java 里面需修改4个参数:tokenLocation、redirectURI、clientId、clientSecret,该参数需由授权提供方提供。
SSLConnectionClient.java
package com.fr; import org.apache.oltu.oauth2.client.HttpClient; import org.apache.oltu.oauth2.client.request.OAuthClientRequest; import org.apache.oltu.oauth2.client.response.OAuthClientResponse; import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory; import org.apache.oltu.oauth2.common.OAuth; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.utils.OAuthUtils; import javax.net.ssl.*; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Map; /**  * Implementation of the OAuth HttpClient using URL Connection  *  *  *  *  */ public class SSLConnectionClient implements HttpClient {     public SSLConnectionClient() {     }     public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,                                                      String requestMethod, Class<T> responseClass)             throws OAuthSystemException, OAuthProblemException {         String responseBody = null;         URLConnection c = null;         int responseCode = 0;         try {             URL url = new URL(request.getLocationUri());             c = url.openConnection();             responseCode = -1;             if (c instanceof HttpsURLConnection) {                 HttpsURLConnection httpsURLConnection = (HttpsURLConnection)c;                 SSLContext sslContext = SSLContext.getInstance("TLS");                 sslContext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new SecureRandom());                 httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());                 httpsURLConnection.setHostnameVerifier(new TrustAnyHostnameVerifier());                 if (headers != null && !headers.isEmpty()) {                     for (Map.Entry<String, String> header : headers.entrySet()) {                         httpsURLConnection.addRequestProperty(header.getKey(), header.getValue());                     }                 }                 if (!OAuthUtils.isEmpty(requestMethod)) {                     httpsURLConnection.setRequestMethod(requestMethod);                     if (requestMethod.equals(OAuth.HttpMethod.POST)) {                         httpsURLConnection.setDoOutput(true);                         OutputStream ost = httpsURLConnection.getOutputStream();                         PrintWriter pw = new PrintWriter(ost);                         pw.print(request.getBody());                         pw.flush();                         pw.close();                     }                 } else {                     httpsURLConnection.setRequestMethod(OAuth.HttpMethod.GET);                 }                 httpsURLConnection.connect();                 InputStream inputStream;                 responseCode = httpsURLConnection.getResponseCode();                 if (responseCode == 400) {                     inputStream = httpsURLConnection.getErrorStream();                 } else {                     inputStream = httpsURLConnection.getInputStream();                 }                 responseBody = OAuthUtils.saveStreamAsString(inputStream);             }         } catch (Exception e) {             throw new OAuthSystemException(e);         }         return OAuthClientResponseFactory                 .createCustomResponse(responseBody, c.getContentType(), responseCode, responseClass);     }     public void shutdown() {         // Nothing to do here     }     static class TrustAnyTrustManager implements X509TrustManager {         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {         }         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {         }         public X509Certificate[] getAcceptedIssuers() {             return new X509Certificate[]{};         }     }     static class TrustAnyHostnameVerifier implements HostnameVerifier {         public boolean verify(String hostname, SSLSession session) {             return true;         }     } } 
2.将org.apache.oltu.oauth2.client-1.0.1.jar 放到对应路径:\WebReport\WEB-INF\lib,org.apache.oltu.oauth2.client-1.0.1.jar中包含OAuth方法。
3.修改配置文件web.xml(该文件在\WebReport\WEB-INF路径下),加上如下代码:
<filter> <filter-name>filter</filter-name>  <filter-class>com.fr.myfilter</filter-class> </filter> <filter-mapping>       <filter-name>filter</filter-name>       <url-pattern>/ReportServer</url-pattern> </filter-mapping> 
4、重启BI服务器,访问以下地址获取code:
https://www.example.com/oauth/authorize?response_type=code&client_id=UnLlynnG6UEtBlK66C6WNzlM&redirect_uri=http://ip:端口号/WebReport/ReportServer?op=fs&scope=1,向OAuth请求Code时,地址中需带以下几个参数授权认证后,方可实现单点登录进入帆软系统。
Parameter NameTypeDescription
client_idstring必须参数,在OAuth注册应用时获得的API Key。
response_typestring必须参数,此值固定为“code”。
redirect_uristring必须参数,授权后要回调的UR I,当前系统通过此地址来获取Code。
scopestring非必须参数,以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限。
注1:做单点登录时,需保证FineBI里存在与另一系统中相同的用户。
注2:FineBI服务启动时会默认自动跳转到浏览器,打开BI平台,可在\FineBI\conf路径下的server.xml中找到以下代码: ,将该行删除,此时启动BI服务时,将不再自动跳转到浏览器打开BI平台了,需要访问时,自行输入访问地址。

注3:因为做了单点登录,通过个人系统页面登录BI,所以有时我们会需要在登出时也跳转至个人系统的登录页面,此时,可在FineBI\webapps\WebReport\WEB-INF\lib中,找到fr-platform-8.0.jar\com\fr\fs\web\frame中的fs.frame.js,搜索signOut,在function方法中找到 window.location.href = res,将其修改为window.location.href = "要登出的地址",保存后重启BI即可实现。


附件列表


主题: 部署集成
标签: 暂无标签 编辑/添加标签
如果您认为本文档还有待完善,请编辑

文档内容仅供参考,如果你需要获取更多帮助,请咨询帆软技术支持
关于技术问题,您还可以通过帆软论坛获取帮助,论坛上有非常多的大神,有些水平比帆软工程师还要高哦。
若您还有其他非技术类问题,可以联系帆软传说哥(qq:1745114201

本文档是否有用?