当前位置:文档之家› 数据处理与分析FineBI如何实现OAuth单点登录

数据处理与分析FineBI如何实现OAuth单点登录

数据处理与分析FineBI如何实现OAuth单点登录
数据处理与分析FineBI如何实现OAuth单点登录

数据处理与分析FineBI如何实现 OAuth单点登录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

1.package com.fr;

2.

3.import https://www.doczj.com/doc/8017640215.html,.hsqldb.lib.StringUtil;

4.

5.import https://www.doczj.com/doc/8017640215.html,.ssl.*;

6.import java.io.*;

7.import https://www.doczj.com/doc/8017640215.html,.HttpURLConnection;

8.import https://www.doczj.com/doc/8017640215.html,.URL;

9.import https://www.doczj.com/doc/8017640215.html,.URLDecoder;

10.import https://www.doczj.com/doc/8017640215.html,.URLEncoder;

11.import java.security.SecureRandom;

12.import java.security.cert.X509Certificate;

13.import java.util.HashMap;

14.import java.util.Map;

15.import java.util.Map.Entry;

16.

17./**

18. * 进行http访问的基本类

19. */

20.public class HttpUtil {

21.

22.private static final String DEFAULT_CHARSET = "UTF-8";

23.

24.private static final String METHOD_POST = "POST";

25.

26.private static final String METHOD_GET = "GET";

27.

28.private static final int CONNECTTIMEOUT = 5000;

29.

30.private static final int READTIMEOUT = 5000;

31.

32.private static class DefaultTrustManager implements X509TrustMa

nager {

33.

34.public X509Certificate[] getAcceptedIssuers() {

35.return null;

36. }

37.

38.@Override

39.public void checkClientTrusted(X509Certificate[] cert, Stri

ng oauthType)

40.throws java.security.cert.CertificateException {

41. }

42.

43.@Override

44.public void checkServerTrusted(X509Certificate[] cert, Stri

ng oauthType)

45.throws java.security.cert.CertificateException {

46. }

47. }

48.

49.private static HttpURLConnection getConnection(URL url, String

method, String ctype)

50.throws IOException {

51. HttpURLConnection conn = null;

52.if ("https".equals(url.getProtocol())) {

53. SSLContext ctx = null;

54.try {

55. ctx = SSLContext.getInstance("TLS");

56. ctx.init(new KeyManager[0], new TrustManager[] { ne

w DefaultTrustManager() },

57.new SecureRandom());

58. } catch (Exception e) {

59.throw new IOException(e);

60. }

61. HttpsURLConnection connHttps = (HttpsURLConnection) url

.openConnection();

62. connHttps.setSSLSocketFactory(ctx.getSocketFactory());

63. connHttps.setHostnameVerifier(new HostnameVerifier() {

64.public boolean verify(String hostname, SSLSession s

ession) {

65.return true;// 默认都认证通过

66. }

67. });

68. conn = connHttps;

69. } else {

70. conn = (HttpURLConnection) url.openConnection();

71. }

72. conn.setRequestMethod(method);

73. conn.setDoInput(true);

74. conn.setDoOutput(true);

75. conn.setRequestProperty("User-Agent", "quantangle-

apiclient-java");

76. conn.setRequestProperty("Content-Type", ctype);

77. conn.setRequestProperty("Connection", "Keep-Alive");

78.return conn;

79. }

80.

81./**

82. * 通过get方法访问,默认编码为utf-8

83. *

84. * @param url 访问的url地址

85. * @param params 请求需要的参数

86. * @return 返回请求响应的数据

87. * @throws IOException

88. */

89.public static String doGet(String url, Map para

ms) throws IOException {

90.return doGet(url, params, DEFAULT_CHARSET);

91. }

92.

93./**

94. * 通过get方法访问

95. *

96. * @param url 访问的url地址

97. * @param params 请求需要的参数

98. * @param charset 字符编码

99. * @return 返回请求响应的数据

100. * @throws IOException

101. */

102.public static String doGet(String url, Map pa rams, String charset)

103.throws IOException {

104.if (StringUtil.isEmpty(url) || params == null) {

105.return null;

106. }

107. String response = "";

108. url += "?" + buildQuery(params, charset);

109. HttpURLConnection conn = null;

110. String ctype = "application/x-www-form-

urlencoded;charset=" + charset;

111. conn = getConnection(new URL(url), METHOD_GET, ctype); 112. response = getResponseAsString(conn);

113.return response;

114. }

115.

116./**

117. *

118. * @param url api请求的权路径url地址

119. * @param params api请求的业务级参数

120. * @return

121. * @throws IOException

122. */

123.public static String doPost(String url, Map p arams) throws IOException {

124.return doPost(url, params, CONNECTTIMEOUT, READTIMEOUT);

125. }

126.

127./**

128. *

129. * 通过post方法请求数据,默认字符编码为utf-8

130. *

131. * @param url 请求的url地址

132. * @param params 请求的参数

133. * @param connectTimeOut 请求连接过期时间

134. * @param readTimeOut 请求读取过期时间

135. * @return 请求响应

136. * @throws IOException

137. */

138.public static String doPost(String url, Map p arams, int connectTimeOut,

139.int readTimeOut) throws IOExcepti on {

140.return doPost(url, params, DEFAULT_CHARSET, connectTimeOu t, readTimeOut);

141. }

142.

143./**

144. *

145. * 通过post方法请求数据

146. *

147. * @param url 请求的url地址

148. * @param params 请求的参数

149. * @param charset 字符编码格式

150. * @param connectTimeOut 请求连接过期时间

151. * @param readTimeOut 请求读取过期时间

152. * @return 请求响应

153. * @throws IOException

154. */

155.public static String doPost(String url, Map p arams, String charset,

156.int connectTimeOut, int readTimeO ut) throws IOException {

157. HttpURLConnection conn = null;

158. String response = "";

159. String ctype = "application/x-www-form-

urlencoded;charset=" + charset;

160. conn = getConnection(new URL(url), METHOD_POST, ctype); 161. conn.setConnectTimeout(connectTimeOut);

162. conn.setReadTimeout(readTimeOut);

163. conn.getOutputStream().write(buildQuery(params, charset).

getBytes(charset));

164. response = getResponseAsString(conn);

165.return response;

166. }

167.

168./**

169. *

170. * @param params 请求参数

171. * @return 构建query

172. */

173.public static String buildQuery(Map params, S tring charset) {

174.if (params == null || params.isEmpty()) {

175.return null;

176. }

177. StringBuilder sb = new StringBuilder();

178.boolean first = true;

179.for (Entry entry : params.entrySet()) { 180.if (first) {

181. first = false;

182. } else {

183. sb.append("&");

184. }

185. String key = entry.getKey();

186. String value = entry.getValue();

187.if (!StringUtil.isEmpty(key) && !StringUtil.isEmpty(v alue)) {

188.try {

189. sb.append(key).append("=").append(URLEncoder.

encode(value, charset));

190. } catch (UnsupportedEncodingException e) {} 191. }

192. }

193.return sb.toString();

194.

195. }

196.

197.public static Map splitQuery(String query, St ring charset) {

198. Map ret = new HashMap();

199.if (!StringUtil.isEmpty(query)) {

200. String[] splits = query.split("\\&");

201.for (String split : splits) {

202. String[] keyAndValue = split.split("\\=");

203.boolean flag=true;

204.int i=0;int len=keyAndValue.length;

205.for (;i

206. {

207.if (StringUtil.isEmpty(keyAndValue[i]))

208. {

209. flag=false;

210.break;

211. }

212. }

213.if (flag && keyAndValue.length == 2) {

214.try {

215. ret.put(keyAndValue[0], URLDecoder.decode (keyAndValue[1], charset));

216. } catch (UnsupportedEncodingException e) {} 217. }

218. }

219. }

220.return ret;

221. }

222.

223.private static byte[] getTextEntry(String fieldName, String f ieldValue, String charset)

224.throws IOException {

225. StringBuilder entry = new StringBuilder();

226. entry.append("Content-Disposition:form-data;name=\""); 227. entry.append(fieldName);

228. entry.append("\"\r\nContent-Type:text/plain\r\n\r\n"); 229. entry.append(fieldValue);

230.return entry.toString().getBytes(charset);

231. }

232.

233.private static byte[] getFileEntry(String fieldName, String f ileName, String mimeType,

234. String charset) throws IOE xception {

235. StringBuilder entry = new StringBuilder();

236. entry.append("Content-Disposition:form-data;name=\""); 237. entry.append(fieldName);

238. entry.append("\";filename=\"");

239. entry.append(fileName);

240. entry.append("\"\r\nContent-Type:");

241. entry.append(mimeType);

242. entry.append("\r\n\r\n");

243.return entry.toString().getBytes(charset);

244. }

245.

246.private static String getResponseAsString(HttpURLConnection c onn) throws IOException {

247. String charset = getResponseCharset(conn.getContentType() );

248. InputStream es = conn.getErrorStream();

249.if (es == null) {

250.return getStreamAsString(conn.getInputStream(), chars et);

251. } else {

252. String msg = getStreamAsString(es, charset);

253.if (StringUtil.isEmpty(msg)) {

254.throw new IOException("{\"" + conn.getResponseCod e() + "\":\"" + conn.getResponseMessage() + "\"}");

255. } else {

256.throw new IOException(msg);

257. }

258. }

259.

260. }

261.

262.private static String getStreamAsString(InputStream input, St ring charset) throws IOException {

263. StringBuilder sb = new StringBuilder();

264. BufferedReader bf = null;

265.try {

266. bf = new BufferedReader(new InputStreamReader(input, charset));

267. String str;

268.while ((str = bf.readLine()) != null) {

269. sb.append(str);

270. }

271.return sb.toString();

272. } finally {

273.if (bf != null) {

274. bf.close();

275. bf = null;

276. }

277. }

278.

279. }

280.

281.private static String getResponseCharset(String ctype) { 282. String charset = DEFAULT_CHARSET;

283.if (!StringUtil.isEmpty(ctype)) {

284. String[] params = ctype.split("\\;");

285.for (String param : params) {

286. param = param.trim();

287.if (param.startsWith("charset")) {

288. String[] pair = param.split("\\=");

289.if (pair.length == 2) {

290. charset = pair[1].trim();

291. }

292. }

293. }

294. }

295.return charset;

296. }

297.

298.}

myexporter.java

1.package com.fr;

2.import com.fr.base.DynamicUnitList;

3.import com.fr.base.FRContext;

4.import com.fr.base.ResultFormula;

5.import https://www.doczj.com/doc/8017640215.html,paratorUtils;

6.import com.fr.general.DeclareRecordType;

7.import com.fr.general.ModuleContext;

8.import com.fr.general.web.ParameterConsts;

9.import com.fr.io.TemplateWorkBookIO;

10.import com.fr.io.exporter.AppExporter;

11.import com.fr.io.exporter.PDFExporter;

12.import com.fr.io.exporter.WordExporter;

13.import com.fr.json.JSONArray;

14.import com.fr.json.JSONException;

15.import com.fr.json.JSONObject;

16.import com.fr.main.TemplateWorkBook;

17.import com.fr.main.workbook.ResultWorkBook;

18.import com.fr.page.PageSetProvider;

19.import com.fr.page.PaperSettingProvider;

20.import com.fr.report.cell.CellElement;

21.import com.fr.report.cell.DefaultTemplateCellElement;

22.import com.fr.report.cell.ResultCellElement;

23.import com.fr.report.cell.cellattr.PageExportCellElement;

24.import com.fr.report.core.ReportUtils;

25.import com.fr.report.core.block.PolyResultWorkSheet;

26.import com.fr.report.module.EngineModule;

27.import com.fr.report.worksheet.PageRWorkSheet;

28.import com.fr.stable.CodeUtils;

29.import com.fr.stable.ColumnRow;

30.import com.fr.stable.PageActor;

31.import com.fr.stable.unit.FU;

32.import com.fr.stable.unit.UNIT;

33.import com.fr.web.Browser;

34.import com.fr.web.core.ErrorHandlerHelper;

35.import com.fr.web.core.utils.ExportUtils;

36.import com.fr.web.utils.WebUtils;

37.import javax.servlet.ServletException;

38.import javax.servlet.http.HttpServlet;

39.import javax.servlet.http.HttpServletRequest;

40.import javax.servlet.http.HttpServletResponse;

41.import java.io.IOException;

42.import java.io.OutputStream;

43.import java.util.*;

44.import java.util.regex.Matcher;

45.import java.util.regex.Pattern;

46.public class myexporter extends HttpServlet {

47.private static boolean offlineWriteAble = true;

48.private static final Pattern KEY_VALUE_PATTERN = https://www.doczj.com/doc/8017640215.html,pil

e("[^{,}]*:[^{,}]*");

49.public static void dealResponse4Export(HttpServletResponse res)

{

50. res.setHeader("Cache-Control", "public");

51. res.setHeader("Cache-Control", "max-age=3");

52. res.reset();

53. }

54.private static final long serialVersionUID = 1L;

55.public void doPost(HttpServletRequest request, HttpServletR

esponse response) throws ServletException, IOException {

56. doGet(request, response);

57. }

58.public void doGet(HttpServletRequest req, HttpServletRespon

se res) throws ServletException, IOException {

59.// 首先需要定义执行所在的环境,这样才能正确读取数据库信息

60.try {

61. ModuleContext.startModule(EngineModule.class.getNam

e());

62. dealResponse4Export(res);

63. String fileName = WebUtils.getHTTPRequestParameter(

req, ParameterConsts.__FILENAME__);

64. String format = WebUtils.getHTTPRequestParameter(re

q, "format");

65. Browser browser = Browser.resolve(req);

66. fileName = browser.getEncodedFileName4Download(file

Name);

67. List paraMapList = new ArrayList();

68. List reportPathList = new ArrayList();

69. PaperSettingProvider paperSettingProvider=null;

70.if (WebUtils.getHTTPRequestParameter(req, Parameter

Consts.REPORTLETS) != null) {

71. createReportsFromReportlets(WebUtils.getHTTPReq

uestParameter(req, ParameterConsts.REPORTLETS), reportPathList, par aMapList);

72. ResultWorkBook[] resultWorkBook = new ResultWor

kBook[reportPathList.size()];

73. PolyResultWorkSheet allInOneSheet = new PageRWo

rkSheet();

74.for (int i = 0; i < reportPathList.size(); i++)

{

75. TemplateWorkBook workbook = TemplateWorkBoo

kIO.readTemplateWorkBook(FRContext.getCurrentEnv(), String.valueOf( reportPathList.get(i)));

76. java.util.Map paraMap = (Map) paraMapList.g

et(i);

77. resultWorkBook[i] = workbook.execute(paraMa

p, new PageActor());

78.if (i==0)

79. {

80. paperSettingProvider=ReportUtils.getPap

erSettingListFromWorkBook(workbook).get(0);

81. }

82. }

83.int countx; int county; int length = result

WorkBook.length;

84.long sumx;long sumy;

85.long[] lengthx = new long[length];long[] l

engthy = lengthx.clone();

86.if (length > 0) {

87. lengthx[0] = lengthy[0] = 0;

88. }

89.for (int i = 1; i < length; i++) {

90. sumy = 0;

91. county = resultWorkBook[i - 1].getEleme

ntCaseReport(0).getRowCount();

92.while (county-- > 0) {

93. sumy = sumy + resultWorkBook[i - 1]

.getElementCaseReport(0).getRowHeight(county).getLen();

94. }

95.

96. lengthx[i] = 0;lengthy[i] = sumy+length

y[i-1];

97. }

98. ArrayList verticalList = new ArrayLis

t();

99. ArrayList horizontalList = new ArrayL

ist();

100. analyElementColumnRow(verticalList, horiz ontalList, resultWorkBook, lengthx, lengthy);

101. allInOneSheet = setNewColRowSize(vertical List, horizontalList, allInOneSheet);

102.//填充空白单元格

103. allInOneSheet = fillBlankCell(verticalLis t.size(), horizontalList.size(), allInOneSheet);

104.for (int i = 0, len = reportPathList.size (); i < len; i++) {

105.//添加当前元素到新sheet中去

106. allInOneSheet = addElemToSheet(vertic alList, horizontalList, allInOneSheet, resultWorkBook[i], lengthx[i ], lengthy[i]);

107. }

108.if (paperSettingProvider==null)

109. {

110.return;

111. }

112.// 将结果工作薄导出为Excel文件

113. doExport(req, res, format, fileName,false, br owser,allInOneSheet.generateReportPageSet(paperSettingProvider)); 114. }

115. }catch(Exception e){

116. e.printStackTrace();

117. }

118. }

119.private static void doExport(HttpServletRequest req, HttpServ letResponse res,String format, String fileName, boolean isEmbbed, B rowser browser,PageSetProvider page) throws Exception {

120. AppExporter[] exporters = new AppExporter[] {null}; 121. DeclareRecordType[] exportTypes = new DeclareRecordType[] {null};

122. OutputStream outputStream = res.getOutputStream();

123. getExporterAndTypeAndexport(req, res, format, fileName, i sEmbbed, browser, exporters,exportTypes,outputStream,page);

124. DeclareRecordType exportType = exportTypes[0];

125.

126.if (exportType == null) {

127. ErrorHandlerHelper.getErrorHandler().error(req, res, "Cannot recognize the specifed export format:" + format + ",\nThe c orrect format can be PDF,Excel,Word,SVG,CSV,Text or Image."); 128.return;

129. }

130.

131.try {

132. outputStream.flush();

133. outputStream.close();

134. } catch (IOException e) {

135.// alex:有些Exporter在export里面可能会已经做了out.close 操作,为了不打印IOException,这里catch到之后不输出

136. }

137. }

138.private static void getExporterAndTypeAndexport(HttpServletRe quest req, HttpServletResponse res,

139. String format, String fileName, boolean isEmbbed, Browser browser, AppExporter[] exporter s, DeclareRecordType[] exportTypes,OutputStream out,PageSetProvider page) throws Exception{

140.if (format.equalsIgnoreCase("PDF")) {

141. ExportUtils.setPDFContent(res, fileName, isEmbbed); 142. PDFExporter PDFExport = new PDFExporter();

143. PDFExport.export(out, page);

144. } else if (format.equalsIgnoreCase("Word")) {

145. ExportUtils.setWordConetent(res, fileName);

146. WordExporter WordExport = new WordExporter();

147. WordExport.export(out, page);

148. }

149. }

150.// private static AppExporter getPDFExporter(HttpServletReques t req, ReportSessionIDInfor sessionIDInfor) {

151.// AppExporter exporter;

152.// String extype = WebUtils.getHTTPRequestParameter(req, "

extype");

153.// // james:是否是PDF客户端打印

154.// boolean isPDFPrint = ComparatorUtils.equals(WebUtils.ge tHTTPRequestParameter(req, "isPDFPrint"), "true");

155.// // 标志是否正在为客户端PDF打印而生成PDF文件

156.// // 打印的话,记录下

157.// if (isPDFPrint) {

158.// LogUtils.recordPrintInfo(sessionIDInfor.getBookPath (), sessionIDInfor.getParameterMap4Execute4Consisent(),

159.// DeclareRecordType.PRINT_TYPE_PDF, sessionID Infor);

160.// if (!Browser.resolve(req).isIE()) {

161.// FRContext.getLogger().error(Inter.getLocText("N S_print_pdf"));

162.// }

163.// }

164.// /*

165.// * 根据sessionIDInfor获取当前的打印机偏移量,若为打印则设置偏移导出则不偏移

166.// */

167.// SetPrinterOffsetService setprinteroffsetservice = new S etPrinterOffsetService();

168.// float[] offset = setprinteroffsetservice.getOffsetBySes sionIDInfor(sessionIDInfor);

169.// sessionIDInfor.setoffset(isPDFPrint ? offset : new floa t[2]);

170.// // carl:两种类型

171.// if (ComparatorUtils.equals(ExportConstants.TYPE_RESOLVE SOMETHING, extype)) {

172.// exporter = new PDFExporter2(isPDFPrint);

173.// } else {

174.// exporter = new PDFExporter(isPDFPrint);

175.// }

176.// return exporter;

177.// }

178.//

179.// private static void dealExcelExporter(HttpServletRequest re q, HttpServletResponse res, ReportSessionIDInfor sessionIDInfor, 180.// AppExporter[] exporte rs, DeclareRecordType[] exportTypes, String fileName, Browser brows er) {

181.// // carl:四种输出方式

182.// String extype = WebUtils.getHTTPRequestParameter(req, "

extype");

183.// // 假如是层式报表默认使用大数据方式

184.// ResultWorkBook wb = sessionIDInfor.getWorkBook2Show();

185.// boolean isPage = true; // 大数据量的时候要不要分页

186.// for (int i = 0; i < wb.getReportCount(); i++) {

187.// if (wb.getReport(i) instanceof LayerReport || wb.ge tReport(i) instanceof LayerPageReport) {

e(extype)) {

189.// isPage = false;

190.// }

191.// if (!ExportConstants.TYPE_PAGETOSHETT.equalsIgn oreCase(extype)) {

192.// extype = ExportConstants.TYPE_LARGEDATA_PAG E;

193.// }

194.// break;

195.// }

196.// }

197.//

198.// if (ExportConstants.TYPE_LARGEDATA_PAGE.equalsIgnoreCas e(extype)) {

199.// ExportUtils.setZipContext(res, fileName, browser.sh ouldSetContentTypeOnZipDownload());

200.// exporters[0] = new LargeDataPageExcelExporter(Repor tUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBoo k()), isPage);

201.// exportTypes[0] = DeclareRecordType.EXPORT_TYPE_EXCE L_LARGE;

202.// } else {

203.// if (ExcelUtils.checkPOIJarExist() && !WebUtils.getH TTPRequestBoolParameter(req, "isExcel2003")) {

204.// ExportUtils.setExcel2007Content(res, fileName);

205.// } else {

206.// ExportUtils.setExcelContent(res, fileName); 207.// }

208.//

209.// if (ExportConstants.TYPE_SIMPLE.equalsIgnoreCase(ex type)) {

210.// exporters[0] = new ExcelExporter(ReportUtils.ge tPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())); 211.// exportTypes[0] = DeclareRecordType.EXPORT_TYPE_ EXCEL_ORIGINAL;

212.// } else if (ExportConstants.TYPE_PAGETOSHETT.equalsI gnoreCase(extype)) {

213.// exporters[0] = new PageToSheetExcelExporter(Rep ortUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextB ook()));

214.// exportTypes[0] = DeclareRecordType.EXPORT_TYPE_ EXCEL_PAGESHEET;

Case(extype)) {

216.// exporters[0] = new StreamExcelExporter(ReportUt ils.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook() ));

217.// exportTypes[0] = DeclareRecordType.EXPORT_TYPE_ EXCEL_ORIGINAL;

218.// } else {

219.// exporters[0] = new PageExcelExporter(ReportUtil s.getPaperSettingListFromWorkBook(sessionIDInfor.getContextBook())) ;

220.// exportTypes[0] = DeclareRecordType.EXPORT_TYPE_ EXCEL_PAGE;

221.// }

222.//

223.// ((ExcelExporter)exporters[0]).setExcel2003(WebUtils .getHTTPRequestBoolParameter(req, "isExcel2003"));

224.// }

225.// }

226.//

227.// private static DeclareRecordType getImageExportType(HttpSer vletRequest req) {

228.// DeclareRecordType[] supportImageType = {DeclareRecordTy pe.EXPORT_TYPE_IMAGE_PNG, DeclareRecordType.EXPORT_TYPE_IMAGE_JPG,

229.// DeclareRecordType.EXPORT_TYPE_IMAGE_GIF, Declar eRecordType.EXPORT_TYPE_IMAGE_BMP, DeclareRecordType.EXPORT_TYPE_IM AGE_WBMP

230.// };

231.// String extype = WebUtils.getHTTPRequestParameter(req, "

extype");

232.// int defaulttype = 0;

233.// if (extype != null) {

234.// for (int i = 0; i < supportImageType.length; i++) {

235.// if (extype.equalsIgnoreCase(supportImageType[i] .getTypeString())) {

236.// defaulttype = i;

237.// break;

238.// }

239.// }

240.// }

241.// return supportImageType[defaulttype];

242.// }

243.public static PolyResultWorkSheet fillBlankCell(int rowCount, int colCount,PolyResultWorkSheet allInOneSheet ){

244.for (int i = 0; i < rowCount; i++) {

245.for (int j = 0; j < colCount; j++) {

246.//填充空白格, 主要是为了方便后续分页取cell iterator.next方便, 不然是null就不往下走了

247. ResultCellElement ce = createDefaultCellElement(j , i);

248. allInOneSheet.addCellElement(ce);

249. }

250. }

251. allInOneSheet.setRowMappingArray(new int[0]);

252. allInOneSheet.setColumnMappingArray(new int[0]);

253.return allInOneSheet;

254. }

255.public static ResultCellElement createDefaultCellElement(int col, int row){

256.return new PageExportCellElement(new DefaultTemplateCellE lement(col, row));

257. }

258.public static PolyResultWorkSheet addElemToSheet(ArrayList< UNIT> verticalList, ArrayList horizontalList, PolyResultWorkS heet page_sheet, ResultWorkBook resultWorkBook,long lengthx,long l engthy){

259. UNIT x= FU.getInstance(lengthx);

260. UNIT y= FU.getInstance(lengthy);

261. DynamicUnitList newRowList = page_sheet.getRowHeightList_ DEC();

262. DynamicUnitList newColList = page_sheet.getColumnWidthLis t_DEC();

263.int rowCount = page_sheet.getRowCount();

264.int colCount = page_sheet.getColumnCount();

265. DynamicUnitList rowHeightList = resultWorkBook.getElement CaseReport(0).getRowHeightList_DEC();

266. DynamicUnitList colWidthList = resultWorkBook.getElementC aseReport(0).getColumnWidthList_DEC();

267. Iterator it = resultWorkBook.getElementCase Report(0).cellIterator();

268. HashMap columnRowMap = new HashMap();

269. HashMap formulaMap = new Hash Map();

270.while(it.hasNext()){

271. CellElement ce = it.next();

272. UNIT ceX = x.add(colWidthList.getRangeValueFromZero(c

e.getColumn()));

273. UNIT ceWidth = colWidthList.getRangeValue(ce.getColum n(), ce.getColumn() + ce.getColumnSpan());

274. UNIT ceY = y.add(rowHeightList.getRangeValueFromZero( ce.getRow()));

275. UNIT ceHeight = rowHeightList.getRangeValue(ce.getRow (), ce.getRow() + ce.getRowSpan());

276.//直接去坐标列表里找, 然后+1, 因为行高list就是根据坐标列表生成的.

277.int newCeCol = horizontalList.indexOf(ceX) + 1; 278.int newCeColSpan = getNewSpan(newCeCol, newColList, c eWidth, colCount);

279.int newCeRow = verticalList.indexOf(ceY) + 1;

280.int newCeRowSpan = getNewSpan(newCeRow, newRowList, c eHeight, rowCount);

281. ColumnRow oriCR = ColumnRow.valueOf(ce.getColumn(), c

e.getRow());

282. ColumnRow newCR = ColumnRow.valueOf(newCeCol, newCeRo w);

283.//记录下格子的变迁, A1->B5, 这样后续公式有用到A1的都改成B5

284. columnRowMap.put(oriCR.toString(), newCR.toString());

285. ResultCellElement newCe = (ResultCellElement) ce.deri veCellElement(newCeCol, newCeRow, newCeColSpan, newCeRowSpan); 286. page_sheet.addCellElement(newCe);

287.if(ce.getValue() instanceof ResultFormula){

288. formulaMap.put(newCe, (ResultFormula) ce.getValue ());

289. }

290. }

291.//改变所有保留公式里的ColumnRow

292. modifyAllFormula(formulaMap, columnRowMap);

293.return page_sheet;

294. }

295.public static int getNewSpan(int newCeColRow, DynamicUnitList newColRowList, UNIT ceWidthHeight, int count){

296.for (int i = newCeColRow; i < count + 1; i++) {

297.if(ComparatorUtils.equals(ceWidthHeight, newColRowLis t.getRangeValue(newCeColRow, i))){

298.return i - newCeColRow;

299. }

300. }

301.

302.return0;

303. }

304.public static PolyResultWorkSheet setNewColRowSize(ArrayL ist verticalList, ArrayList horizontalList, PolyResu ltWorkSheet allInOneSheet){

305.//从坐标列表里生成行高列宽 [0, 2, 6] -> [2, 4]

306.for (int i = 0; i < verticalList.size(); i++) {

307. UNIT lastCoordinate = i == 0 ? UNIT.ZERO : verticalLi st.get(i - 1);

308. UNIT rowHeight = verticalList.get(i).subtract(lastCoo rdinate);

309. allInOneSheet.setRowHeight(i, rowHeight);

310. }

311.

312.for (int i = 0; i < horizontalList.size(); i++) {

313. UNIT lastCoordinate = i == 0 ? UNIT.ZERO : horizontal List.get(i - 1);

314. UNIT colWidth = horizontalList.get(i).subtract(lastCo ordinate);

315. allInOneSheet.setColumnWidth(i, colWidth);

316. }

317.return allInOneSheet;

318. }

319.public static void analyElementColumnRow(ArrayList vert icalList, ArrayList horizontalList,

320. ResultWorkBook [] re sultWorkBooks,long [] lengthx,long [] lengthy){

321.int length=resultWorkBooks.length;

322.for (int i=0;i

323. ResultWorkBook resultWorkBook = resultWorkBooks[i]; 324. UNIT y = FU.getInstance(lengthy[i]);

325.int rowCount = resultWorkBook.getElementCaseReport(0) .getRowCount();

326. DynamicUnitList rowHeightList = resultWorkBook.getEle mentCaseReport(0).getRowHeightList_DEC();

327. analyColumnRow(y, verticalList, rowHeightList, rowCou nt);

328.

329.//列处理

330. UNIT x = FU.getInstance(lengthx[i]);

331.int colCount = resultWorkBook.getElementCaseReport(0) .getColumnCount();

332. DynamicUnitList colWidthList = resultWorkBook.getElem entCaseReport(0).getColumnWidthList_DEC();

333. analyColumnRow(x, horizontalList, colWidthList, colCo unt);

334.

335.//得到的多个块, 需要按序排列下, 才好切行高

336. }

337. sort(verticalList, horizontalList);

338. }

339.public static void analyColumnRow(UNIT startPoint, ArrayList verticalSet,

340. DynamicUnitList rowHeightL ist, int count){

341. verticalSet.add(startPoint);

342.for (int i = 0; i < count; i++) {

343. UNIT rowHeight = rowHeightList.getRangeValueFromZero(

i + 1);

344. UNIT rowY = rowHeight.add(startPoint);

345. verticalSet.add(rowY);

346. }

347. }

348.public static void sort(ArrayList verticalList, Array List horizontalList){

349.

350. Comparator compare = new Comparator() { 351.

352.public int compare(UNIT o1, UNIT o2) {

353.if (o1.subtract(o2).equal_zero()){

354.return0;

355. }

356.

357.return o1.subtract(o2).more_than_zero() ? 1 : -1;

358. };

359. };

360.

361. Collections.sort(verticalList, compare);

362. Collections.sort(horizontalList, compare);

363. }

364.private static void modifyAllFormula(HashMap formulaMap, HashMap columnRowMap){ 365. Iterator> formulaIt = formulaMap.entrySet().iterator();

366.while(formulaIt.hasNext()){

统一认证与单点登录系统-产品需求规格说明书

统一认证与单点登录系统产品需求规格说明书 北京邮电大学

版本历史

目录 0文档介绍 (5) 0.1 文档目的 (5) 0.2 文档范围 (5) 0.3 读者对象 (5) 0.4 参考文档 (5) 0.5 术语与缩写解释 (5) 1产品介绍 (7) 2产品面向的用户群体 (7) 3产品应当遵循的标准或规范 (7) 4产品范围 (7) 5产品中的角色 (7) 6产品的功能性需求 (8) 6.0 功能性需求分类 (8) 6.0.1产品形态 (8) 6.1 外部系统管理 (9) 6.1.1外部系统注册 (9) 6.1.2外部系统集成配置 (11) 6.2 用户管理 (11) 6.2.1用户管理控制台 (11) 6.2.2用户自助服务 (13) 6.2.3统一用户管理 (13) 6.3 组织结构管理 (14) 6.4 权限管理 (15) 6.4.1统一角色管理 (18) 6.5 单点登录 (18) 6.5.1基于Httpheader单点登录 (19) 6.5.2基于表单代填的方式单点登录 (20) 6.5.3基于CAS单点登录 (20) 6.5.4总结 (23) 7产品的非功能性需求 (24) 7.1.1性能需求 (24) 7.1.2接口需求 (24) 8附录B:需求确认 (25)

0文档介绍 0.1文档目的 此文档用于描述统一认证与单点登录系统的产品需求,用于指导设计与开发人员进行系统设计与实现。 0.2文档范围 本文档将对系统的所有功能性需求进行消息的描述,同时约定非功能性以及如何与第三方系统进行交互。 0.3读者对象 本文档主要面向一下读者: 1.系统设计人员 2.系统开发与测试人员 3.系统监管人员 4.产品甲方管理人员 0.4参考文档 《凯文斯信息技术有限公司单点登录及统一用户技术方案V1.0》 0.5术语与缩写解释

一个Web应用单点登录系统的设计和实现

第20卷哈尔滨师范大学自然科学学报 Vol.20,No.12004 第1期 NATURAL SCIENCES JOURNAL OF HARBIN NORMAL UNIVERSITY 一个Web 应用单点登录系统的设计和实现 陈重威 (上海市静安区业余大学) 摘要 作者在分析借鉴三种Web 单点登录产品和技术的基础上,设计并实现了一个Web 单点登录系统,该系统适用于企业内部Intranet 应用环境,可以跨多个In ternet 域,可以支持常见的几种操作系统和Web 应用服务器.本文介绍了此系统的设计思路和关键技术,并给出了部分关键代码. 关键词:Web;HTTP;单点登录;身份验证 收稿日期:2003-12-28 陈重威,(1948-),男,上海静安区业余大学计算机系副教授,主要研究方向:计算机网络、数据库 0 引言 经过多年的建设,我国企业中建立起来了一些基于Web 的应用系统,这些系统运行在多种操作系统和应用服务器上面,由不同的技术人员在不同的时期采用不同的技术建立,采用多种相互独立的用户管理、身份验证系统.在当前企业有限的经费预算条件下,如何使用户可以只登录企业信息系统一次就可以访问到企业中多种Web 应用一直是一种挑战.本文在分析三种具有代表性的Web 应用单点登录系统的基础上,针对中小型企业对Web 应用单点登录的要求、其Intranet 环境的特点,给出一个适应于中小型企业Intranet 内常见Web 应用的单点登录系统的设计框架及基于J2EE 的系统实现要点. 1 用户要求和现有产品 1 1 用户环境和要求 企业中基于Web 的应用系统种类繁多,有基于微软Internet Information Server 的运行在Windows 平台上的信息系统,有基于J2EE 应用服务器平台 的业务系统,有基于Lotus Domino 的办公自动化 系统,也有SAP 、ORAC LE 那样的ERP 系统或者财 务系统,这些系统各有各的用户数据库(关系型数据库、Domino 文档数据库、LDAP 服务器等).企业员工在不同应用系统中有不同的帐户!!!用户名和口令,他们需要牢记这些帐户.企业员工特别希望只登录一次就可以透明地访问其他各种应用系统,不再需要在各种应用系统的登录页面中多次输入不同的用户名和口令. 从用户的角度看,Web 应用单点登录系统的使用方法如下: 1 用户访问Web 单点登录系统,服务器返回登录页面,提示用户输入用户名和口令等认证信息; 2 用户登录系统,登录系统返回一个该用户有权访问的应用的列表; 3 自此以后,用户访问其他应用的时候,在用户看来,他不必进行身份验证就可以访问其他Web 应用了; 4 当用户退出一个应用系统,而没有退出?单点登录系统#,他仍然可以访问其他没有退出登录的应用系统.

简单的单点登录实现过程及效果展示

一、实现过程 从用到的jar包文件夹的cas-server-3.3.1modules中找出cas.war放到tomcat/webapps下面(cas-server-webapp-3.3.1.war重命名即可)。 现在cas默认的server端已经有了,下面自己写2个客户端测试一下 MyEclipse里面新建web project:sso 新建类HelloWorldExample package servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public final class HelloWorldExample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html");

PrintWriter writer = response.getWriter(); writer.println(""); writer.println(""); writer.println("Sample Application Servlet Page"); writer.println(""); writer.println(""); writer.println("

"); writer.println(""); writer.println(""); writer.println(""); writer.println(""); writer.println("
"); writer.println(""); writer.println(""); writer.println("

Sample Application Servlet

"); writer.println("This is the output of a servlet that is part of"); writer.println("the Hello, World application."); writer.println("
");

统一认证系统_设计方案

基础支撑平台

第一章统一身份认证平台 一、概述 建设方案单点登录系统采用基于Liberty规范的单点登录ID-SSO系统平台实现,为数字化校园平台用户提供安全的一站式登录认证服务。为平台用户以下主要功能: 为平台用户提供“一点认证,全网通行”和“一点退出,整体退出”的安全一站式登录方便快捷的服务,同时不影响平台用户正常业务系统使用。用户一次性身份认证之后,就可以享受所有授权范围内的服务,包括无缝的身份联盟、自动跨域、跨系统访问、整体退出等。 提供多种以及多级别的认证方式,包括支持用户名/密码认证、数字证书认证、动态口令认证等等,并且通过系统标准的可扩展认证接口(如支持JAAS),可以方便灵活地扩展以支持第三方认证,包括有登录界面的第三方认证,和无登录界面的第三方认证。 系统遵循自由联盟规范的Liberty Alliance Web-Based Authentication 标准和OASIS SAML规则,系统优点在于让高校不用淘汰现有的系统,无须进行用户信息数据大集中,便能够与其无缝集成,实现单点登录从而建立一个联盟化的网络,并且具有与未来的系统的高兼容性和互操作性,为信息化平台用户带来更加方便、稳定、安全与灵活的网络环境。 单点登录场景如下图所示:

一次登录认证、自由访问授权范围内的服务 单点登录的应用,减轻了用户记住各种账号和密码的负担。通过单点登录,用户可以跨域访问各种授权的资源,为用户提供更有效的、更友好的服务;一次性认证减少了用户认证信息网络传输的频率,降低了被盗的可能性,提高了系统的整体安全性。 同时,基于联盟化单点登录系统具有标准化、开放性、良好的扩展性等优点,部署方便快捷。 二、系统技术规范 单点登录平台是基于国际联盟Liberty规范(简称“LA”)的联盟化单点登录统一认证平台。 Liberty规范是国际170多家政府结构、IT公司、大学组成的国际联盟组织针对Web 单点登录的问题提供了一套公开的、统一的身份联盟框架,为客户释放了使用专用系统、不兼容而且不向后兼容的协议的包袱。通过使用统一而又公开的 Liberty 规范,客户不再需要为部署多种专用系统和支持多种协议的集成复杂度和高成本而伤脑筋。 Liberty规范的联盟化单点登录SSO(Single Sign On)系统有以下特点: (1). 可以将现有的多种Web应用系统联盟起来,同时保障系统的独立性,提供单点 登录服务;

单点登录系统(SSO)详细设计说明书

单点登录系统(SSO)详细设计说明书 1、引言 1.1编写目的 为了单点登录系统(SSO系统)的可行性,完整性,并能按照预期的设想实现该系统,特编写需求说明书。 同时,说明书也发挥与策划和设计人员更好地沟通的作用。 1.2背景 a.鉴于集团运营的多个独立网站(称为成员站点),每个网站都具有自己的身份验证机制,这样势必造成:生活中的一位用户,如果要以会员的身份访问网站,需要在每个网站上注册,并且通过身份验证后,才能以会员的身份访问网站;即使用户以同样的用户名与密码在每个网站上注册时,虽然可以在避免用户名与密码的忘记和混淆方面有一定的作用,但是用户在某一段时间访问多个成员站点或在成员站点间跳转时,还是需要用户登录后,才能以会员的身份访问网站。这样不仅给用户带来了不便,而且成员网站为登录付出了性能的代价; b.如果所有的成员网站,能够实现单点登录,不仅在用户体验方面有所提高,而且真正体现了集团多个网站的兄弟性。通过这种有机结合,能更好地体现公司大平台,大渠道的理念。同时,这样做也利于成员网站的相互促进与相互宣传。 正是出于上面的两点,单点登录系统的开发是必须的,是迫在眉睫的。1.3定义 单点登录系统提供所有成员网站的“单一登录”入口。本系统的实质是含有身份验证状态的变量, 在各个成员网站间共用。单点登录系统,包括认证服务器(称Passport服务器),成员网站服务器。 会员:用户通过Passport服务器注册成功后,就具有了会员身份。 单一登录:会员第一次访问某个成员网站时,需要提供用户名与密码,一旦通过Passport服务器的身份验证, 该会员在一定的时间内,访问任何成员网站都不需要再次登录。 Cookie验证票:含有身份验证状态的变量。由Passport服务器生成,票含有用户名,签发日期时间, 过期日期时间和用户其它数据。

单点登录技术方案

xxxx集团 单点登录技术方案

目录 1. xxxx集团系统建设现状 (4) 1.1. Web应用系统 (4) 1.2. C/S应用系统 (4) 1.3. SSL VPN系统 (4) 2. xxxx集团单点登录系统需求 (5) 2.1. 一站式登录需求 (5) 3. SSO(单点登录)技术简介 (6) 3.1. 修改应用程序SSO方案 (6) 3.2. 即插即用SSO方案 (7) 3.3. 两种SSO方案比较 (7) 3.4. 惠普SSO (7) 3.4.1. 惠普SSO开发背景 (7) 3.4.2. 惠普SSO的功能 (8) 3.4.3. 惠普SSO的特点 (9) 3.4.4. 惠普SSO结构 (10) 4. xxxx集团单点登录技术方案 (11) 4.1. 应用系统中部署惠普SSO单点登录 (11) 4.1.1. 解决全局的单点登录 (12) 4.1.2. 应用系统的整合 (12) 4.1.3. 用户如何过渡到使用单点登录 (13) 4.1.4. 管理员部署业务系统单点登录功能 (14) 4.1.5. 建立高扩展、高容错单点登录环境 (15) 4.1.6. 建立稳定、安全、高速网络环境 (15) 4.2. 定制工作 (16) 4.2.1. SSL VPN结合 (16)

4.2.2. 密码同步 (16) 5. 项目实施进度 (17) 5.1. 基本安装配置 (17) 5.2. 配置认证脚本 (17) 5.3. 总体进度 (17) 6. 硬件清单 (19) 7. 软件清单 (20)

1.xxxx集团系统建设现状 xxxx集团有限责任公司(以下简称集团公司)管理和运营省内11个民用机场,以及20多个关联企业(全资子公司、控股企业、参股企业)。现有的信息系统主要有生产运营系统和管理信息系统,其中生产运营系统包括机场生产运营管理系统、中小机场生产运营管理系统、离港系统、航显系统、广播系统、安检信息管理系统、控制区证件管理系统等,管理信息系统主要有财务系统、OA 系统、邮件系统、资产管理系统、决策支持系统、网站信息发布审批系统、视频点播系统等。这些信息系统的用户包括集团公司所有机场以及关联企业。 各信息系统都有独立的用户组织体系,采用“用户名+密码”的方式来实现身份认证和授权访问。从而与众多企业一样存在如下一些主要问题:1、终端用户需要记住多个用户名和密码;2、终端用户需要登录不同的信息系统以获取信息;3、系统管理员难以应付对用户的管理;4、难以实施系统使用安全方面的管理措施。 1.1.Web应用系统 xxxx集团现有的Web应用系统包括:办公自动化系统(OA)、邮件系统、资产管理系统、内部网站信息发布审批系统、决策支持系统、视频点播系统等。这些系统基本上是各自独立开发的、或者购买的商业软件。每个应用系统都有自己的用户管理机制和用户认证机制,彼此独立。每个应用系统用户名、口令可能各不相同。 1.2.C/S应用系统 xxxx集团目前的C/S应用只有一个:财务系统,金蝶K3财务系统。 1.3.SSL VPN系统 xxxx集团有一套SSL VPN系统,集团局域网之外的用户(包括各地州机场、部分关联企业、用户自己家住房、出差旅馆、无线上网等)是通过SSL VPN 系统进入集团局域网的,通过SSL VPN系统进入集团局域网访问的系统包括:OA系统、邮件系统、资产管理系统、决策支持系统、网站信息发布审批系统及内部网站等。用户经过SSL VPN系统进入集团局域网需要经过身份认证。

项目概要设计说明书

XX公司 概要设计说明书模板(2014年)

目录 第1 章......................... 简介1 1.1 编写目的 (1) 1.2 文档的控制 (1) 1.3 文档的审批 (1) 1.4 项目干系人 (2) 2.1 业务发展方向 (2) 2.2 当前组织结构 (2) 2.3 当前IT 环境 (3) 2.4 标准约定 (3) 第3 章................... 探索方案和方法3 3.1项目定义............... (3) 3.2系统上下文............. (3) 3.3主题模型............... (4) 3.4功能性需求列表......... (5) 第2 章.................. 业务和需要的理解

3.5 非功能性需求列表 ..................... 8 3.6 用例图 (10) 10 4.1 应用架构概况图 ..................... 10 4.2 架构决策 ........................ 11 4.3 架构部件(组件)模型图 .................. 13 4.4 系统运行部署图 ..................... 13 4.5 项目计划 .............. 错误! 4.6 项目的例外责任 ............ 错误! 4.7 项目依赖 .............. 错误! 4.8 风险和规避 .............. 错误! 4.9 问题和假设 .............. 错误! 4.10 假设条件 .............. 错误! 第5章 .................... 16 5.1 服务级别标准 ....................... 16 5.2 服务资源及规范 (16) 主要业务名词和术语定义 .................... 17 参考文献 . (17) 第4章 .................... 项目交付架构 未定义书签。 未定义书签。 未定义书签。 未定义书签。 未定义书签。 未定义书签。 运营支撑标准

SSO 原理浅谈

SSO 原理浅谈 SSO 是一个非常大的主题,我对这个主题有着深深的感受,自从广州UserGroup 的论坛成立以来,无数网友都在尝试使用开源的CAS ,Kerberos 也提供另外一种方式的SSO ,即基于Windows 域的SSO ,还有就是从2005 年开始一直兴旺不衰的SAML 。 如果将这些免费的SSO 解决方案与商业的Tivoli 或Siteminder 或RSA Secure SSO 产品做对比,差距是存在的。毕竟,商业产品的安全性和用户体验都是无与伦比的,我们现在提到的SSO ,仅仅是Web SSO ,即Web-SSO 是体现在客户端;另外一种SSO 是桌面SSO ,例如,只需要作为Administrator 登录一次windows 2000 ,我便能够在使用MSN/QQ 的时候免去登录的环节( 注意,这不是用客户端软件的密码记忆功能) ,是一种代理用户输入密码的功能。因此,桌面SSO 是体现在OS 级别上。 今天,当我们提起SSO 的时候,我们通常是指Web SSO ,它的主要特点是,SSO 应用之间走Web 协议( 如HTTP/SSL) ,并且SSO 都只有一个登录入口。 简单的SSO 的体系中,会有下面三种角色: 1 ,User (多个) 2 ,Web 应用(多个) 3 ,SSO 认证中心(1 个) 虽然SSO 实现模式千奇百怪,但万变不离其宗: l Web 应用不处理User 的登录,否则就是多点登陆了,所有的登录都在SSO 认证中心进行。l SSO 认证中心通过一些方法来告诉Web 应用当前访问用户究竟是不是张三/ 李四。 l SSO 认证中心和所有的Web 应用建立一种信任关系,SSO 认证中心对用户身份正确性的判断会通过某种方法告之Web 应用,而且判断结果必须被Web 应用信任。 2. CAS 的基本原理 CAS(Central Authentication Service) 是Yale 大学发起的一个开源项目,据统计,大概每10 个采用开源构建Web SSO 的Java 项目,就有8 个使用CAS 。对这些统计,我虽然不以为然,但有一点可以肯定的是,CAS 是我认为最简单实效,而且足够安全的SSO 选择。 本节主要分析CAS 的安全性,以及为什么CAS 被这样设计,带着少许密码学的基础知识,我希望有助于读者对CAS 的协议有更深层次的理解。 2.1 CAS 的结构体系 从结构体系看,CAS 包含两部分: l CAS Server CAS Server 负责完成对用户的认证工作,CAS Server 需要独立部署,有不止一种CAS Server 的实现,Yale CAS Server 和ESUP CAS Server 都是很不错的选择。 CAS Server 会处理用户名/ 密码等凭证(Credentials) ,它可能会到数据库检索一条用户帐号信息,也可能在XML 文件中检索用户密码,对这种方式,CAS 均提供一种灵活但同一的接口/ 实现分离的方式,CAS 究竟是用何种认证方式,跟CAS 协议是分离的,也就是,这个认证的实现细节可以自己定制和扩展。 l CAS Client CAS Client 负责部署在客户端(注意,我是指Web 应用),原则上,CAS Client 的部署意味着,当有对本地Web 应用的受保护资源的访问请求,并且需要对请求方进行身份认

java实现简单的单点登录(4)

下面是登录模块DesktopSSOLoginModule的主体:login()方法。逻辑也是非常简单:先用Cookie来登陆,如果成功,则直接就进入系统,否则需要用户输入用户名和密码来登录系统。 public boolean login() throws LoginException{ try { if (Cookielogin()) return true; } catch (IOException ex) { ex.printStackTrace(); } if (passwordlogin()) return true; throw new FailedLoginException(); } 下面是Cookielogin()方法的实体,它的逻辑是:先从Cookie文件中获得相应的Cookie值,通过身份效验服务效验Cookie的有效性。如果cookie有效就算登录成功;如果不成功或Cookie不存在,用cookie登录就算失败。 public boolean Cookielogin() throws LoginException,IOException { String cookieValue=""; int cookieIndex =foundCookie(); if (cookieIndex<0) return false; else cookieValue = getCookieValue(cookieIndex); username = cookieAuth(cookieValue); if (! username.equals("failed")) { loginSuccess = true; return true; } return false; } 用用户名和密码登录的方法要复杂一些,通过Callback的机制和屏幕输入输出进行信息交互,完成用户登录信息的获取;获取信息以后通过userAuth方法来调用远端SSOAuth的服务来判定当前登录的有效性。 public boolean passwordlogin() throws LoginException { // // Since we need input from a user, we need a callback handler if (callbackHandler == null) {

单点登录SSO系统解决方案

单点登录SSO系统 解决方案 ***有限公司 20

文档信息版本历史

目录 1.概述 (5) 1.1.背景 (5) 1.2.目标 (5) 1.3.阅读对象 (5) 1.4.术语和缩略语 (5) 2.SSO概述 (6) 2.1.SSO规范 (6) 2.1.1.名称解释 (6) 3.SSO接口规范 (7) 3.1.SSO接口图 (7) 3.2.SSO接口清单 (7) 3.3.单点登录接口 (8) 3.3.1.登录 (8) 3.3.2.登录状态检查 (10) 3.3.3.用户信息获取 (11) 3.3.4.登录状态查询 (12) 3.3.5.单点登录使用场景 (12) 3.4.组织数据WS同步 (13) 3.4.1.接口说明 (13) 3.4.2.使用场景 (13) 3.4.3.字段说明 (13) 3.4.4.业务规则和逻辑 (14)

3.5.用户数据WS同步 (15) 3.5.1.接口说明 (15) 3.5.2.使用场景 (15) 3.5.3.字段说明 (15) 3.5.4.业务规则和逻辑 (16) 4.实施建议 (17) 4.1.SSO实施(基本认证) (17) 4.1.1.接入流程 (17) 4.1.2.接入准备 (18) 4.1.3.接收数据 (18) 4.1.4.登录状态检查方法 (18) 4.1.5.登录/检查登录状态成功—主体代码(Success URL)编写 (18) 4.1.6.登录失败处理 (19) 4.1.7.状态检查未登录处理 (19) 4.2.组织和用户接收 (19) 4.2.1.开发框架 (19) 4.2.2.开发过程 (19) 5.附录 (20) 5.1.SSO E RROR C ODE (20) 5.2.SSO T OKEN XML (20) 5.3.SSO用户信息 (20) 5.4.SSO获取用户信息失败的状态码 (20)

单点登录技术文档

济南时代智囊科技有限公司单点登录技术文档
单点登录技术文档
何伟民* 2010.6
1、 单点登录概述 、
单点登录的英文名称为 Single Sign-On,简写为 SSO,它是一个用户认证的过程,允许 用户一次性进行认证之后,就访问系统中不同的应用;而不需要访问每个应用时,都重新输 入密码。IBM 对 SSO 有一个形象的解释“单点登录、全网漫游” 。 SSO 将一个企业内部所有域中的用户登录和用户帐号管理集中到一起,SSO 的好处显 而易见: 1. 减少用户在不同系统中登录耗费的时间,减少用户登录出错的可能性 2. 实现安全的同时避免了处理和保存多套系统用户的认证信息 3. 减少了系统管理员增加、删除用户和修改用户权限的时间 4. 增加了安全性:系统管理员有了更好的方法管理用户,包括可以通过直接禁止和删除用 户来取消该用户对所有系统资源的访问权限 对于内部有多种应用系统的企业来说, 单点登录的效果是十分明显的。 很多国际上的企 业已经将单点登录作为系统设计的基本功能之一。
1.1 单点登录产品
商业 SSO 软件 专门的 SSO 商业软件 主要有:Netgrity 的 Siteminder,已经被 CA 收购。Novell 公司的 iChain。RSA 公 司的 ClearTrust 等。 门户产品供应商自己的 SSO 产品, 如:BEA 的 WLES,IBM 的 Tivoli Access Manager,Sun 公司的 identity Server, Oracle 公司的 OID 等。 上述商业软件一般适用于客户对 SSO 的需求很高,并且企业内部采用 Domino、SAP、 Sieble 等系统比较多的情况下。单点登录产品通常需要在应用软件中增加代理模块,而商业 SSO 产品主要针对大型软件制作了代码模块。 因此,商业 SSO 软件除了价格问题外,另一个重要问题就是对客户自己的应用系统支 持未必十分完善。
第1页

单点登录设计原理

https://www.doczj.com/doc/8017640215.html,/j2eeweiwei/article/details/2381332 单点登录设计原理 分类:权限控管Java 2008-05-04 13:12 244人阅读评论(0) 收藏举报 本文以某新闻单位多媒体数据库系统为例,提出建立企业用户认证中心,实现基于安全策略的统一用户管理、认证和单点登录,解决用户在同时使用多个应用系统时所遇到的重复登录问题。 随着信息技术和网络技术的迅猛发展,企业内部的应用系统越来越多。比如在媒体行业,常见的应用系统就有采编系统、排版系统、印刷系统、广告管理系统、财务系统、办公自动化系统、决策支持系统、客户关系管理系统和网站发布系统等。由于这些系统互相独立,用户在使用每个应用系统之前都必须按照相应的系统身份进行登录,为此用户必须记住每一个系统的用户名和密码,这给用户带来了不少麻烦。特别是随着系统的增多,出错的可能性就会增加,受到非法截获和破坏的可能性也会增大,安全性就会相应降低。针对于这种情况,统一用户认证、单点登录等概念应运而生,同时不断地被应用到企业应用系统中。 统一用户管理的基本原理 一般来说,每个应用系统都拥有独立的用户信息管理功能,用户信息的格式、命名与存储方式也多种多样。当用户需要使用多个应用系统时就会带来用户信息同步问题。用户信息同步会增加系统的复杂性,增加管理的成本。 例如,用户X需要同时使用A系统与B系统,就必须在A系统与B系统中都创建用户X,这样在A、B任一系统中用户X的信息更改后就必须同步至另一系统。如果用户X需要同时使用10个应用系统,用户信息在任何一个系统中做出更改后就必须同步至其他9个系统。用户同步时如果系统出现意外,还要保证数据的完整性,因而同步用户的程序可能会非常复杂。 统一存储(UUMS)、分布授权: 解决用户同步问题的根本办法是建立统一用户管理系统(UUMS)。UUMS统一存储所有应用系统的用户信息,应用系统对用户的相关操作全部通过UUMS完成,而授权等操作则由各应用系统完成,即统一存储、分布授权。

单点登录SSO的定义实现机制及优缺点

一、什么是单点登录S S O(S i n g l e S i g n-O n) SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。 二、单点登录解决了什么问题 解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。 三、单点登录的技术实现机制 如下图所示: 当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。 从上图可以看出sso的实现技术点: 1)所有应用系统共享一个身份认证系统。 统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。 2)所有应用系统能够识别和提取ticket信息 要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。 关于统一身份认证机制:如下图 ?①用户请求访问业务系统。 ②业务系统在系统中查看是否有对应请求的有效令牌,若有,则读取对应的身份信息,允许其访问;若没有或令牌无效,则把用户重定向到统一身份认证平台,并携带业务系统地址,进入第③步。 ③在统一身份认证平台提供的页面中,用户输入身份凭证信息,平台验证此身份凭证信息,若有效,则生成一个有效的令牌给用户,进入第④步;若无效,则继续进行认证,直到认证成功或退出为止。 ④用户携带第③步获取的令牌,再次访问业务系统。 ⑤业务系统获取用户携带的令牌,提交到认证平台进行有效性检查和身份信息获取。 ⑥若令牌通过有效性检查,则认证平台会把令牌对应的用户身份信息返回给业务系统,业务系统把身份信息和有效令牌写入会话状态中,允许用户以此身份信息进行业务系统的各种操作;若令牌未通过有效性检查,则会再次重定向到认证平台,返回第③步。 通过统一身份认证平台获取的有效令牌,可以在各个业务系统之间实现应用漫游。 四、单点登录的优点

单点登录技术文档

单点登录技术文档 张昀* 2006.12 说明:本文档在我们最大努力范围之内确保其正确性、实效性和可观性,但并不代表所有的观点都是正确的,而仅代表个人看法。如发现不当之处,请多指教,谢谢! 另外,本文并不是给初学者看的。虽然我们尽可能把每个概念和操作步骤都说得比较明白,但是如果您对于Linux系统不是很熟的话,很多操作仍然可能存在困难。这种情况下我们建议您直接下载虚拟机安装试用,边实践边学习。 联系邮件:mypersonal1971@https://www.doczj.com/doc/8017640215.html,。 1、单点登录概述 单点登录的英文名称为Single Sign-On,简写为SSO,它是一个用户认证的过程,允许用户一次性进行认证之后,就访问系统中不同的应用;而不需要访问每个应用时,都重新输入密码。IBM对SSO有一个形象的解释“单点登录、全网漫游”。 SSO将一个企业内部所有域中的用户登录和用户帐号管理集中到一起,SSO的好处显而易见: 1. 减少用户在不同系统中登录耗费的时间,减少用户登录出错的可能性 2. 实现安全的同时避免了处理和保存多套系统用户的认证信息 3. 减少了系统管理员增加、删除用户和修改用户权限的时间 4. 增加了安全性:系统管理员有了更好的方法管理用户,包括可以通过直接禁止和删除用户来取消该用户对所有系统资源的访问权限 对于内部有多种应用系统的企业来说,单点登录的效果是十分明显的。很多国际上的企业已经将单点登录作为系统设计的基本功能之一。 1.1单点登录产品 商业SSO软件 ●专门的SSO商业软件 ?主要有:Netgrity的Siteminder,已经被CA收购。Novell 公司的iChain。RSA公 司的ClearTrust等。 ●门户产品供应商自己的SSO产品, ?如:BEA的WLES,IBM 的Tivoli Access Manager,Sun 公司的identity Server, Oracle公司的OID等。

单点登录分析与设计

目录 1、概述 (3) 2、功能需求 (4) 2.1、身份认证标识管理 (4) 2.2、消息协议 (5) 2.3、日志管理 (5) 3、系统设计 (6) 3.1、网络结构 (6) 3.1、体系架构 (6) 3.2、功能模块 (8) 3.3、数据模型 (9) 3.4、系统接口 (10) 3.4.1、用户登录 (10) 3.4.2、切换认证 (13) 3.4.3、登记接口 (13) 3.4.4、签退 (14) 3.4.5、认证 (15) 4、系统实现 (17) 4.1、用户联系类 (17) 4.2、业务系统信息设置 (17) 4.3、访问业务系统 (18) 4.4、配置文件 (22) 4.5、核心代码 (23) 5、系统测试 (26) 5.1、测试概述 (26) 5.2、测试用例 (26) 5.2.1、用户登录 (26) 5.2.2、切换认证 (28) 5.2.3、签出 (28)

5.2.4、认证 (29) 5.2.5、坐席登录 (30) 5.3、测试结果 (30)

1、概述 单点登录系统在企业信息化平台中作为企业用户、个人用户、平台管理员用户登录注册系统,通过单点登录系统信息化平台中的这三类用户可以实现单点登录多平台访问。实现方式是这三类用户通过单点登录系统进行登录时产生一个登陆表示,通过这个平台唯一的登录标识可以从业务系统跳转到另外一个业务信息。 单点登录系统不存在业务数据维护功能,所以单点登录系统不提供页面功能。单点登录系统的所有功能通过多个WebService接口对外提供,当然这些接口请 求也会通过IP认证的方式进行安全认证。同时对于业务系统进行二次开发会提 供一个开发工具包,开发工具包的主要作用是实现XML字符串和类对象之间的相互转换。 统一身份认证分为业务方面和性能方面两类。 业务问题包括: 1.业务管理人员如何实现跨平台管理。 2.教师、学生实现跨平台查看自己的业务数据。 3.业务系统如何改造满足跨平台访问。 性能问题包括: 1.每一次登录需要进行记录,系统管理人员可以查询。 2.每一次平台之间的切换需要进行记录,系统管理人员可以查询。 3.如何保证网络安全。 4.每秒访问次数不少于80次(单个应用)。 5.应用可以实现堆砌部署,随时添加机器和应用。

基于CAS模式的单点登录系统设计与分析

Computer Science and Application 计算机科学与应用, 2019, 9(7), 1434-1440 Published Online July 2019 in Hans. https://www.doczj.com/doc/8017640215.html,/journal/csa https://https://www.doczj.com/doc/8017640215.html,/10.12677/csa.2019.97161 Design and Analysis of Single Sign on System Based on CAS Mode Xiaowei Xu, Jinlei Wang, Wenfei Jiang, Fengjuan Cui North China Sea Data and Information Service, SOA, Qingdao Shandong Received: Jul. 9th, 2019; accepted: Jul. 22nd, 2019; published: Jul. 29th, 2019 Abstract In order to solve the problem of the integration of the existing business application system of NCS, this paper makes a deep research on the principle of CAS integrated authentication, and designs a single sign on system based on CAS mode. Based on the actual situation of various software systems of NCS, this paper analyzes the problems faced by various systems to achieve single sign-on, propos-es different solutions to these problems, and provides technical route for the integration of business application systems of NCS, so as to realize the construction of single sign-on system of NCS. Keywords CAS Authentication, SSO, System Integration 基于CAS模式的单点登录系统设计与分析 徐晓玮,王金磊,姜雯斐,崔凤娟 国家海洋局北海信息中心,山东青岛 收稿日期:2019年7月9日;录用日期:2019年7月22日;发布日期:2019年7月29日 摘要 针对自然资源部北海局现有业务应用系统整合问题,对CAS集成认证原理进行深入研究,设计搭建了基于CAS模式的单点登录系统。结合北海局各类软件系统的实际情况,分析各类系统实现单点登录所面临的问题,针对这些问题提出不同的解决方案,为北海局业务应用系统的整合集成提供技术路线,以实现北海局单点登录系统的建设。

【黑马程序员】单点登录实现原理(SSO)

【黑马程序员】单点登录实现原理(SSO) 简介 ?单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源,像一些知名的大型网站,如:淘宝与天猫、新浪微博与新浪博客等都用到了这个技术。 原理 ?单点登录 ?有一个独立的认证中心,只有认证中心才能接受用户的用户名和密码等信息进行认证,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过 令牌实现,当用户提供的用户名和密码通过认证中心认证后,认证中心会创建授权 令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到 令牌即得到了授权,然后创建局部会话。 ?示例:

下面对上图进行解释: ?当用户还没进行用户登录的时候 ?用户去访问系统1的保护资源,系统1检测到用户还没登录,跳转至SSO认证中心,SSO认证中心也发现用户没有登录,就跳转到用户至认证中心的登录页面 ?用户在登录页面提交用户相应信息后,认证中心会校验用户信息,如果用户信息正确的话认证中心就会创建与该用户的全局会话(全局会话过期的时候,用户就需要重新登录了。全局会话中存的信息可能有令牌,用户信息,及该在各个系统的一些情况),同时创建授权令牌,然后进行下一步,否则认证中心给出提示(用户信息有误),待用户再次点击登录的时候,再一次进行校验用户信息

?认证中心带着令牌跳转到用户最初请求的地址(系统1),系统1拿到令牌后去SSO认证中心校验令牌是否有效,SSO认证中心校验令牌, 若该令牌有效则进行下一步 ?注册系统1,然后系统1使用该令牌创建和用户的局部会话(若局部会话过期,跳转至SSO认证中心,SSO认证中心发现用户已经登录, 然后执行第3步),返回受保护资源 ? 用户已经通过认证中心的认证后 用户访问系统2的保护资源,系统2发现用户未登录,跳转至SSO认证中心,SSO 认证中心发现用户已经登录,就会带着令牌跳转回系统2,系统2拿到令牌后去SSO 认证中心校验令牌是否有效,SSO认证中心返回有效,注册系统2,系统2使用该令牌创建与用户的局部会话,返回受保护资源。 ? ? 如果系统1的局部会话存在的话,当用户去访问系统1的保护资源时,就直接返回保护资源,不需要去认证中心验证了 ? 局部会话存在,全局会话一定存在;全局会话存在,局部会话不一定存在;全局会话销毁,局部会话必须销毁 如果在校验令牌过程中发现客户端令牌和服务器端令牌不一致或者令牌过期的话,则用户之前的登录就过期了,用户需要重新登录 关于令牌可参考:基于跨域单点登录令牌的设计与实现 ?单点注销

单点登录_尚学堂CAS讲义

一.SSO (Single Sign-on)原理 SSO 分为Web-SSO和桌面SSO。桌面SSO 体现在操作系统级别上。Web-SSO体现在客户端,主要特点是:SSO 应用之间使用Web 协议( 如HTTPS) ,并且只有一个登录入口。我们所讲的SSO,指Web SSO 。 SSO 的体系中,有下面三种角色: ?User(多个) ?Web应用(多个) ?SSO认证中心(一个) SSO 实现模式千奇百怪,但万变不离其宗,包含以下三个原则: ●所有的登录都在 SSO 认证中心进行。 ●SSO 认证中心通过一些方法来告诉 Web 应用当前访问用户究竟是不是通过认证的 用户。 ●SSO 认证中心和所有的 Web 应用建立一种信任关系。 二.CAS 的基本原理 CAS(Central Authentication Service) 是Yale 大学发起的构建Web SSO 的Java开源项目。 1.CAS 的结构体系 ◆CAS Server CAS Server 负责完成对用户信息的认证,需要单独部署,CAS Server 会处理用户名/ 密码等凭证(Credentials) 。 ◆CAS Client CAS Client部署在客户端,当有对本地Web 应用受保护资源的访问请求,并且需要对请求方进行身份认证,重定向到CAS Server 进行认证。 2.CAS 协议 基础协议

上图是一个基础的CAS 协议,CAS Client 以过滤器的方式保护Web 应用的受保护资源,过滤从客户端过来的每一个Web 请求,同时,CAS Client 会分析HTTP 请求中是否包请求Service Ticket( 上图中的Ticket) ,如果没有,则说明该用户是没有经过认证的,CAS Client 会重定向用户请求到CAS Server (Step 2 )。Step 3 是用户认证过程,如果用户提供了正确的认证信息,CAS Server 会产生一个随机的Service Ticket ,会向User 发送一个Ticket granting cookie (TGC) 给User 的浏览器,并且重定向用户到CAS Client (附带刚才产生的Service Ticket),Step 5 和Step6 是CAS Client 和CAS Server 之间完成了一个对用户的身份核实,用Ticket 查到Username ,认证通过。 3.CAS 如何实现SSO 当用户访问Helloservice2再次被重定向到CAS Server 的时候,CAS Server 会主动获到这个TGC cookie ,然后做下面的事情: 1)如果User 的持有TGC 且其还没失效,那么就走基础协议图的Step4 ,达到了 SSO 的效果。 2)如果TGC 失效,那么用户还是要重新认证( 走基础协议图的Step3) 。 三.实践配置 下面我们以tomcat 5.5 为例进行说明(这里,我将Server和Client同时放在了同一个Tomcat服务器下)。 软件环境:tomcat 5.5 ant-1.6.5, jdk1.5.0_06 下载cas-server-3.0.4.zip和cas-client和cas-server-jdbc-3.0.5-rc2.jar和mysql 5.0.16和tomcat 5.5.15 https://www.doczj.com/doc/8017640215.html,/downloads/cas/cas-server-3.0.4.zip

相关主题
文本预览
相关文档 最新文档