北京諾必達科技有限公司致遠OA系統企業門戶集成開發服務分享
.1. 概述
協同平臺的企業門戶提供統一的入口和統一的用戶,將業務系統、報表通過單點登錄和頁面集成方式有機的整合在一起。
-
入口的集成
通過菜單、空間、關聯系統等方式為業務系統提供入口,基于角色進行權限控制,單點登錄后進入業務系統。
-
數據的集成
通過欄目呈現業務數據和報表。
-
消息的集成
接收業務系統的消息,提醒用戶進入異構系統進行處理。
同時,協同平臺也可以作為欄目或整體被第三方Portal(如Websphere Portal、NC Portal)集成。
1.2. 頁簽集成
將第三方系統作為系統的一個頁簽,點擊以后單點登錄進入第三方系統的指定頁面。
平臺開發手冊.Portal集成.頁簽集成.
1.2.1. Spring配置文件
實現頁簽需要建立2個Spring配置文件,下面以nc為例:
1.pluginCfg.xml配置文件
位置:【webapps\seeyon\WEB-INF\cfgHome\plugin\nc1】
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>nc1</id>
<name>NC插件</name>
<category>54321</category>
</plugin>
注意:這里的文件名nc1應該與nc1一致。
2.Bean 配置文件
位置:【webapps\seeyon\WEB-INF\cfgHome\plugin\nc1\spring\spring-nc-manager.xml】
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="erp" class="com.seeyon.ctp.portal.sso.thirdpartyintegration.ThirdpartySpace" init-method="init">
<!-- id必須唯 而且ID必須為數字否則點擊頁簽會報錯一 -->
<property name="id" value="54321"/>
<!-- 頁簽上顯示的名稱 -->
<property name="name" value="ERP空間"/>
<!-- 插件id,必須存在,如果不存在,請按下面的步驟定義一個新的插件 -->
<property name="pluginId" value="nc1"/>
<!-- 第三方系統登錄地址,如果合并3、4步,可以省略 -->
<property name="loginURL" value="http://xxx.xxx.xxx.xxx/seeyon/extform.jsp"/>
<!-- 點擊頁簽要打開的第三方系統頁面地址 -->
<property name="pageURL" value="http://xxx.xxx.xxx.xxx/seeyon/info.jsp"/>
<!-- 打開方式,值為open時在新窗口打開,為workspace時在A8頁面能打開 -->
<property name="openType" value="workspace"/>
<!-- 排序號 -->
<property name="index" value="4"/>
<!-- 授權 accessRoles與accessCheck選擇其中一個即可-->
<property name="accessRoles">
<list>
<value>GeneralStaff</value>
</list>
</property>
<!-- <property name="accessCheck" ref="accessCheck"/> -->
</bean>
<!-- <bean id="accessCheck" class="com.seeyon.ctp.ext.Tab.TestThirdpartyAccessCheck"></bean> -->
</beans>
注意:上面accessRoles與accessCheck在作用都是授權,根據實際需求選擇其一即可。
1.2.2. accessRoles與accessCheck授權區別
1.accessCheck授權:編碼控制授權
accessCheck授權需要繼承ThirdpartyAccessCheck,如果已經有方法獲取當前自定義頁簽使用人員范圍的方法可以直接在這里判斷,如下:
import com.seeyon.ctp.portal.sso.thirdpartyintegration;
public class TestThirdpartyAccessCheck
implements ThirdpartyAccessCheck
{
public boolean check(long memberId)
{
boolean hasErpPermission = BasicInformation.getUserMapper(Long.valueOf(memberId));
// 返回true的人員顯示頁簽
return hasErpPermission;
}
}
2,accessRoles授權:基于角色授權
1.2.3. 注意事項
增加的頁簽并不會直接顯示,需要有權限的人員在【個人事務】-【空間導航設置】中從備選空間進行選擇。
1.3. 擴展菜單集成
擴展菜單,增加模塊或第三方集成的入口。
1.3.1. 主菜單擴展
接口介紹
1、因V5 RBAC的特殊性,不再支持3.5插件菜單以下兩個特性 :
- 可通過管理員菜單權限管理控制菜單是否顯示。
- 可通過配置固定角色如FormAdmin控制權限。
以上兩類需求可以通過超級管理員super-admin增加資源實現。
2、二次開發能夠通過插件開發增加主菜單。
3、菜單項可以使用代碼在運行期控制是否顯示。
4、考慮到開發和實施的分離,為便于實施部署,不采用Web管理界面添加方式。
5、需要同時考慮降低3.5的二次開發遷移工作量。
6、沿襲3.5的實現,只支持一級和二級菜單的定義,不支持更多級別。
通過超級管理員配置來實現系統中主菜單的擴展功能,通過擴展來作為系統各模塊或與第三方集成的入口。
支持以下菜單:
- 前端用戶的一級或多級菜單(0-N個)
- 系統中其他任意角色的一級或多級菜單(0-N個)
配置實現主菜單擴展[V6.0產品不支持此擴展方式]
登錄數據維護
開放目前標準產品屏蔽的賬戶,執行如下預制SQL:
-- 超級管理員人員
INSERT INTO org_member (ID,NAME,CODE,IS_INTERNAL,IS_LOGINABLE,IS_VIRTUAL,IS_ADMIN,IS_ASSIGNED,TYPE,STATE,IS_ENABLE,IS_DELETED,STATUS,SORT_ID,ORG_DEPARTMENT_ID,ORG_POST_ID,ORG_LEVEL_ID,ORG_ACCOUNT_ID,DESCRIPTION,CREATE_TIME,UPDATE_TIME)
VALUES ('6725175934914479521','超級管理員','','1','1','0','1','1',NULL,'1','1','0','1','-1','-1','-1','-1','-1730833917365171641','','2012-08-27 00:00:00','2012-08-27 00:00:00');
-- 超級管理員賬號
INSERT INTO org_principal VALUES ('28','super-admin','tAXR7dJpxqF5GptnLve33dzGGUs=','',NULL,'6725175934914479521','1','2012-08-27 00:00:00','2012-08-27 00:00:00');
-- 超級管理員的關系
INSERT INTO org_relationship (ID,TYPE,SOURCE_ID,OBJECTIVE0_ID,OBJECTIVE1_ID,OBJECTIVE5_ID,SORT_ID,ORG_ACCOUNT_ID,CREATE_TIME,UPDATE_TIME)
VALUES ('-8329422661916671085','Member_Role','6725175934914479521','-1730833917365171641','-3989205346588222483','Member','-1','-1730833917365171641','2012-08-27 00:00:00','2012-08-27 00:00:00');
重啟服務后即可使用超級管理員賬戶登錄,登錄名為super-admin,密碼為123456。
建議在完成菜單配置后,手動刪除這三條記錄并重啟服務。
資源維護
使用超級管理員登錄后,進入【產品打包管理】--【產品資源注冊】
點擊【新建】創建資源,截圖為資源維護界面
自定義的資源保存成功后,在自定義資源列表中可以使用找到該資源,勾選即可進行【編輯】操作。
菜單維護
【產品打包管理】--【產品打包】
可以在左側菜單樹通過點擊后新建菜單來創建二級菜單,或者直接點擊菜單資源樹來創建一級菜單。
這里可以通過選擇是否為虛節點來控制點擊是否產生動作,當選擇不是虛節點時,需要配置頁面資源名稱,此時點擊選擇即可找到上一小節維護的自定義資源。
角色與菜單維護
菜單新建完成后,使用單位管理員或集團管理員登錄,【組織模型管理】--【角色與權限設置】,可以新建或使用現有角色,通過分配資源來分配剛剛新建的菜單即可。
登錄擁有該角色的人員,即可看見配置好的菜單,并且點擊可以訪問配置自定義資源的URL地址,至此菜單的擴展已經全部配置完成。
插件開發實現主菜單擴展
主菜單定義
在插件的Spring配置文件中增加下面的bean定義來增加主菜單。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean parent="pluginMainMenu">
<!-- 主菜單ID,唯一的數字串 -->
<property name="id" value="1111111111" />
<!-- 主菜單名稱 -->
<property name="name" value="NC組織數據同步" />
<!-- 主菜單排序號 -->
<property name="sortId" value="1" />
<!-- 二級菜單 -->
<property name="children">
<list>
<bean class="com.seeyon.ctp.plugin.PluginMenu">
<!-- 二級菜單ID,唯一的數字串 -->
<property name="id" value="1111111112" />
<!-- 二級菜單名稱 -->
<property name="name" value="菜單權限控制" />
<!-- 菜單打開方式 mainfrm:工作區; newWindow:新窗口-- >
<property name="target" value="mainfrm" />
<!-- 菜單圖標 -->
<property name="icon" value="/apps_res/plugin/nc/images/2401.gif" />
<!-- 菜單地址,出于安全方面考慮此url必須是協同內部界面,如果想跳轉請在內部界面實現跳轉 -->
<property name="url" value="/index/indexController.do?method=searchAll" />
<!-- 菜單訪問權限的驗證類 -->
<property name="menuCheck">
<bean class="com.seeyon.ctp.menu.check.UserMenuCheck" />
</property>
</bean>
</list>
</property>
<!-- 菜單訪問權限的驗證類 -->
<property name="menuCheck">
<bean class="com.seeyon.ctp.menu.check.UserMenuCheck" />
</property >
</bean>
</beans>
每一個插件定義的菜單都是獨立的主菜單,暫不支持在指定位置添加子菜單項。
主菜單權限控制
實現一個AbstractMenuCheck的實現類,通過傳入的登錄人員信息控制是否顯示, 并配置到菜單定義的XML中。
集團管理員菜單權限控制代碼示例:
package com.seeyon.ctp.menu.check;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class GroupAdminMenuCheck extends AbstractMenuCheck {
private static final Log log = LogFactory.getLog(GroupAdminMenuCheck.class);
@Override
public boolean check(long memberId, long loginAccountId) {
boolean isAdmin = false;
//TODO判斷是否是集團管理員
return isAdmin;
}
}
為了支持原有的userMenus、groupMenus、accountMenus、systemMenus等特性,系統缺省提供以下幾個MenuCheck :
1.com.seeyon.ctp.menu.check.GroupAdminMenuCheck 集團管理員菜單權限校驗
2.com.seeyon.ctp.menu.check.AccountAdminMenuCheck 單位管理員菜單權限校驗
3.com.seeyon.ctp.menu.check.SystemAdminMenuCheck 系統管理員菜單權限校驗
4.com.seeyon.ctp.menu.check.AuditAdminMenuCheck 審計管理員菜單權限校驗
5.com.seeyon.ctp.menu.check.UserMenuCheck 非管理員菜單權限校驗(普通用戶)
6.com.seeyon.ctp.menu.check.MenuForAllUsersChecker 針對所有用戶菜單全部驗證通過
1.4. 添加自定義菜單
1、定義菜單項:
以文檔菜單為例,在\webapps\seeyon\WEB-INF\cfgHome\plugin\doc\spring 下新建一個 xml 文件(如 docAddinMenu.xml)。代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName" default-lazy-init="false" default-dependency-check="none">
<!-- 自定義加載項菜單,如果要添加多個菜單項,可以在當前的XML文件中定義多個bean,也可 以建立多個XML文件,在menu.xml注冊 -->
<bean id="docAddinMenuItem" class="com.seeyon.ctp.common.thirdparty.menu.ThirdpartyAddinMenu" init-method="init">
<!--菜單添加的功能模塊(頁面),與頁面Controller中定義的的名稱相同,可以在多個頁面 中添加同一菜單項 -->
<property name="module">
<list>
<value>apps/doc/rightNew</value>
</list>
</property>
<!--菜單文本,在資源文件中的名稱。 -->
<property name="label" value="doc.menu.export.label"/>
<!--菜單鏈接,目前只支持javascript,對于文檔交換,可以調用thirdPMenuSend方法,它會 將選中的id發送到指定的地址 -->
<property name="url" value="http://xxxxxx"/>
<!--顯示順序 -->
<property name="index" value="0"/>
</bean>
</beans>
2、指定菜單要添加到的頁面 修改 docAddinMenu.xml 文件,將要顯示的頁面列在 module 下面。如:
<property name="module">
<list>
<value>apps/doc/rightNew</value>
</list>
</property>
此段代碼中”/doc/rightNew”是根據執行流程來找到要添加菜單頁面的地址的。執行流程可以根據頁面屬性查看頁 面請求的地址如 doc.do?meithod=rightNew&…,然后到 webapps\seeyon\WEB-INF\classes 目錄下找 urlMapping,找到 prop key=doc.do 對應的控制文件:docController,進入 classes 目錄下的 doc-controller.xml 文件根據 id=”docController”的 bean 的 class 值找到處理文件(如 com/seeyon/ctp/doc/controller/DocController),根據處理方法 rightNew(與上面的 doc.do?method=rightNew&…相對應)找到 rightNew。
3.指定菜單文本在資源文件中的名稱
修改 docAddminMenu.xml 文件,給 label 加上值。value 值指定的是在頁面上要顯示的值,這里不直接寫上內容是為了后面顯示國際化做準備。
<property name="label" value="doc.menu.export.label"/>
4.指定點擊菜單后進入的頁面地址
修改 docAddinMenu.xml 文件的 url 值,可以是網址,也可以是 javascript。
<property name="url" value="/seeyon/doc/docFile.jsp"/>
5、國際化
在 \webapps\seeyon\WEB-INF\cfgHome\plugin\doc\i18n 文件夾下新建或修改 DocMenuResources_en.properties 和 DocMenuResources_zh_CN.properties 文件,在 DocMenuResources_en.properties 中添加當是英文顯示的時候要顯示的值。如:
doc.menu.export.label=export
在 DocMenuResources_zh_CN.properties 中添加用漢語要顯示的值。如:
doc.menu.export.label=歸檔到文檔系統
用命令將 DocMenuResources_zh_CN.properties 編譯,如:
native2ascii 文件名 新文件名
編譯結果如:
doc.menu.export.label==\u5F52\u5230\u6863\u6848\u7CFB\u7EDF
1.5. 欄目集成(Portlet)
1.5.1. 欄目開發
Portlet在協同中的概念是首頁空間中的一個區域,它可以包含多個Tab(欄目)。Portlet的開發也就是對欄目的開發。
1.5.2. IFrame集成
不需要開發,通過配置關聯系統和擴展欄目,將第三方系統的頁面直接包裝為協同平臺的欄目。操作步驟詳見單點登錄一節的關聯系統和擴展欄目。
1.5.3. SDK+web service方式集成
實現方式為按照插件規范在平臺中開發一個插件,直接連接第三方系統數據庫或利用Web Service讀取第三方系統的數據,按欄目規范組織好以后在協同系統中展現。
確定欄目數據
欄目中的數據由首頁應用來確定
需要提供的接口:
1、數據列表抽取接口,該接口用來獲取欄目顯示的數據;
2、數據總數統計接口,該接口用來顯示欄目數據的總數(如果需求顯示數據總數)。
欄目解析類開發
1.Package:com.seeyon.ctp.portal.section
2.解析類需要繼承抽象類:com.seeyon.ctp.portal.section.BaseSectionImpl
3.Demo類示例
public class DemoSection extends BaseSectionImpl {
@Override
public String getId() {
//欄目ID,必須與spring配置文件中的ID相同;如果是原欄目改造,請盡量保持與原欄目ID一致
return "demoSection";
}
@Override
public String getName(Map preference) {
//欄目顯示的名字,必須實現國際化,在欄目屬性的“columnsName”中存儲
String name = preference.get("columnsName");
if(Strings.isBlank(name)){
return "demoSection";
}else{
return name;
}
}
@Override
public Integer getTotal(Map preference) {
//欄目需要展現總數據條數時重寫
return null;
}
@Override
public String getIcon() {
// 欄目圖標,暫不需要實現
return null;
}
@Override
public BaseSectionTemplete projection(Map preference) {
//欄目解析主方法
HtmlTemplete ht = new HtmlTemplete();
StringBuilder html = new StringBuilder();
html.append("
DemoSection");
ht.setHeight("230");
ht.setHtml(html.toString());
ht.setModel(HtmlTemplete.ModelType.inner);
ht.setShowBottomButton(true);
ht.addBottomButton(BaseSectionTemplete.BOTTOM_BUTTON_LABEL_MORE, "javascript:alert('ok');");
return ht;
}
}
欄目解析類配置
1.編寫好的欄目類需要在對應的插件Spring配置文件夾進行Spring注冊配置。
2.約定欄目的Spring文件命名為spring-xxxx-section.xml xxxx為插件Id。
3.欄目屬性對照表
屬性名 | 值域 | 描述 |
---|---|---|
sectionType | common, //常用欄目 timeManagement, //時間管理 publicInformation, //公共信息 doc, //文檔欄目 formbizconfigs, //表單欄目 forum, //擴展欄目 | 欄目類型,空間選擇欄目時欄目的分類由該屬性決定 |
sectionCategory | plan | 欄目類型中的分類:常用、計劃... |
spaceTypes | Constants.SpaceType中枚舉的類型 | 允許添加該欄目的空間類型 |
resourceBundle | 示例:com.seeyon.v3x.main.resources.i18n.MainResources | 國際化綁定來源,已廢棄 |
properties | List | 欄目編輯屬性 |
4.空間類型
/**
* 空間類型,順序不可改變
*/
public static enum SpaceType {
/**
* 0 個性化個人空間
*/
personal, //0
/**
* 部門空間
*/
department, //1
/**
* 單位空間
*/
corporation, //2
/**
* 集團空間
*/
group, //3
/**
* 自定義團隊空間
*/
custom, //4
//默認的空間
/**
* 默認個人空間
*/
Default_personal, //5
//@Deprecated
/**
* 默認部門空間
*/
Default_department, //6
@Deprecated
Default_custom, //7
/**
* 第三方系統
*/
thirdparty, //8
/**
* 默認領導空間
*/
default_leader,//9
/**
* 個性化領導空間
*/
leader,//10
/**
* 關聯系統
*/
related_system,//11
/**
* 關聯項目
*/
related_project,//12
/**
* 自定義個人空間
*/
Default_personal_custom,//13
/**
* 默認外部人員空間
*/
Default_out_personal,//14
/**
* 個性化個人自定義空間
*/
personal_custom,//15
/**
* 個性化外部人員空間
*/
outer,//16
/**
* 自定義單位空間
*/
public_custom,//17
/**
* 自定義集團空間
*/
public_custom_group,//18
//二級主頁空間
/**
* 協同工作
*/
cooperation_work,//19 協同工作
/**
* 目標管理
*/
objective_manage,//20 目標管理
/**
* 公文管理
*/
edoc_manage,//21 公文管理
/**
* 會議管理
*/
meeting_manage,//22 會議管理
/**
* 協同駕駛艙
*/
performance_analysis,//23 協同駕駛艙
/**
* 空間模板的默認空模板類型,不是空間類型,內部使用
*/
template,//空間模板的默認空模板類型,不作為空間類型使用
/**
* 表單應用
*/
form_application,//25 表單應用
//end
}
5.Demo欄目配置示例
<bean id="demoSection" class="com.seeyon.ctp.portal.section.DemoSection" init-method="init">
<property name="sectionType" value="common" />
<property name="sortId" value="99" />
</bean>
6.欄目模板列表
模板類 | 描述 |
---|---|
CalendarFourColumnTemplete | 日程事件的四列模板:標題 開始時間 結束時間 狀態 |
ChessboardTemplete | 棋盤式 左邊小圖標(默認1616)+右邊標題 上邊大圖標(默認3232)+下邊標題 * 標題可以有浮動菜單 |
ChessMultiRowThreeColumnTemplete | 棋盤式 、3列 |
HtmlTemplete | 直接輸出HTML代碼片斷 |
MonthCalendarTemplate | 月歷式欄目 |
MoveMultiRowThreeColumnTemplete | 多行3列滾動式 |
MultiIconCategoryItem |
多行的,圖標,分類,文本的展現形式 圖表是32px 32px的,在左邊,右邊的上面是分類(Category),下面是若干個項 |
MultiRowFourColumnTemplete | 多行3列模板,依次是:subject createDate createMemberName category |
MultiRowThreeColumnTemplete | 多行3列模板,依次是:subject createDate category |
MultiRowVariableColumnTemplete | 成倍行,不定列 模板 適用于 三或四列標準列表模板滿足不了需要的情況下 可以自定義列數、寬度、單元格樣式、鏈接地址 |
MultiSubjectSummary | 多行的,顯示標題和摘要,常用新聞、公告 |
OneImageAndListTemplete | 圖片加列表模板 第一列為圖片居左 右邊為標題加摘要 下面為列表 列表內容為 標題 發起時間 所屬板塊 * 列表參數可配置 |
OneItemUseTwoRowTemplete | 兩行展現一項 模板 適用于 如集團空間調查欄目 第1行 標題,另起一行 發布時間和類型 |
OnePictureTemplete | 圖片滾動式 |
OneSummaryAndMultiList | 顯示模式:一條顯示為“標題+時間+(類別)+摘要”,下面是若干行列表 |
PictureTemplete | 圖片基礎模板 |
PictureTitleAndBriefTemplete | 標題加摘要的新聞模板 |
1.6. 單點登錄(SSO)
1.6.1. 協同平臺單點登錄第三方系統
實現方式一:關聯系統+擴展欄目
無需開發,使用關聯系統管理登錄信息,集成第三方系統頁面。
適用于不需要驗證碼的Web應用,使用目標系統的用戶名和密碼模擬登錄過程。
-
配置關聯系統
-
以系統管理員system登錄協同,使用“關聯系統管理”建立一個新的關聯系統。關聯系統的url為被集成系統的登錄鏈接,將登錄需要的信息如用戶名和密碼定義為關聯系統參數
-
建立擴展欄目
由第三方系統管理驗證信息的欄目有兩種:數據集成型欄目(SSOWebContentSection)和功能操作型欄目(SSOIframeSection)
-

- 用戶登錄后,在個人空間中配置關聯系統參數,填寫集成系統的登錄信息(用戶名和密碼)。 由關聯系統維護被集成系統的用戶名、密碼以及Session
- 說明:被集成系統的修改:登錄不成功,需要在登錄請求的response中增加header項:LoginError=*,否則平臺無法判斷是否成功登錄
- 從V7.0開始,關聯系統的URL中可以調用公式,實現一些更復雜的單點登錄,請參見公式組件。
實現方式二:Ticket
實現步驟:
-
添加頁簽
新建插件sso:按下面的定義,在協同的webapps\seeyon\WEB-INF\cfgHome\plugin\sso目錄下新建一個XML文件pluginCfg.xml,例如:
<?xml version="1.0" encoding="UTF-8"?> <plugin> <id>sso</id> <name>單點登錄模塊</name> <category>11001</category> </plugin>
然后在協同的webapps\seeyon\WEB-INF\cfgHome\plugin\sso\spring目錄下新建一個XML文件,如myspace.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="byName"> <!-- id必須唯一 --> <bean id="sinaNewsSpace" class="com.seeyon.v3x.common.thirdparty.ThirdpartySpace" init-method="init"> <!--注意如果OA的版本是V6.0及其以上,上面class修正為:com.seeyon.ctp.portal.sso.thirdpartyintegration.ThirdpartySpace --> <!-- id必須唯一或者不寫后臺自動生成,必須為數字 --> <property name="id" value="-2327812443752403806"/> <!-- 頁簽上顯示的名稱 --> <property name="name" value="Sina News"/> <!-- 插件id,必須存在,如果不存在,請按下面的步驟定義一個新的插件 --> <property name="pluginId" value="sso"/> <!-- 第三方系統登錄地址,如果合并3、4步,可以省略 --> <property name="loginURL" value="http://xxx.xxx.xxx.xxx/ssologin.jsp"/> <!-- 點擊頁簽要打開的第三方系統頁面地址 --> <property name="pageURL" value="http://xxx.xxx.xxx.xxx/main.jsp"/> <!-- 打開方式,值為open時在新窗口打開,為workspace時在協同頁面能打開 --> <property name="openType" value="open"/> <!-- 排序號 --> <property name="index" value="4"/> <!-- 授權 accessRoles與accessCheck選擇其中一個即可--> <property name="accessRoles"> <list> <value>GeneralStaff</value> </list> </property> <!-- <property name="accessCheck" ref="accessCheck"/> --> </bean> <!-- <bean id="accessCheck" class="com.seeyon.ctp.ext.Tab.TestThirdpartyAccessCheck"></bean> --> </beans>
注意事項:集成的第三方系統,必須先在協同平臺中定義插件
- myspace.xml參數說明
名稱 | 備注 |
---|---|
id | 唯一標示,這了在XML里必須設置為數字型 |
name | 名稱 |
pluginId | 插件ID |
loginURL | 在進入第三方指定頁面前,先跳轉到loginURL進行握手 第三方系統根據Ticket回調獲取協同身份信息,進行單點登錄,并注冊Ticket和登錄用戶的映射, 平臺帶著Ticket跳轉到第三方系統的"頁面地址" (pageURL) |
pageURL | 第三方指定到達的目的頁面。 |
openType | 打開方式 |
accessRoles與accessCheck | OA用戶對于第三方頁簽顯示權限,詳情請見頁簽集成。 |
-
配置第三方系統,ThirdpartySpace:名稱、登錄地址、頁面地址、打開方式【詳情請見1.5.1. 頁簽集成】
-
登錄過程
在協同中點擊"空間頁簽"
平臺產生Ticket,并維護在內存中
平臺帶著Ticket訪問第三方系統的"登錄地址"(loginURL)進行握手 第三方系統根據Ticket回調獲取協同身份信息,進行單點登錄,并注冊Ticket和登錄用戶的映射, 平臺帶著Ticket跳轉到第三方系統的"頁面地址" (pageURL)
說明
第三方系統完全依賴和信任協同的身份驗證,Ticket由協同平臺發放
第三方系統使用與協同完全相同的登錄名或者進行二次開發,自己維護協同登錄名與第三方系統用戶的映射表
如果當前用戶已經登錄第三方系統,將跳過② ③,直接到第4步,使用相同的Ticket
-
認證ticket/獲取身份信息的接口系統提供Servlet:http://a8:80/seeyon/thirdpartyController.do?ticket=**;平臺將通過response header的LoginName返回登錄名
-
如果第三方回調后認為有異常,請在response header增加名稱為SSOLogoutError的信息
-
在上面myspace.xml中(loginURL)獲取當前人員登錄名例程如下:
//獲取ticket String ticketinfo=request.getParameter("ticket"); //通過ticket/獲取身份信息的接口獲取登錄信息 String LoginNameUrl="http://127.0.0.1/seeyon/thirdpartyController.do?ticket="+ticketinfo; //通過HttpClientUtil發送請求 HttpClientUtil u = new HttpClientUtil(); //獲取登錄名 String LoginName=u.getContent(LoginNameUrl).toString();
第三方系統退出時,要通知協同,地址是http://a8:80/seeyon/thirdparty.do?method=logoutNotify&ticket=**
根據情況可將 ③ ④步合并 (省略loginURL)
1.6.2. 第三方系統單點登錄協同平臺
Ticket中請不要使用特殊字符和中文,平臺不支持使用中文作為Ticket!
必須在配置工具的系統參數設置中配置協同平臺的外網訪問地址internet.site.url,否則,生成的url為空。
注意:【V6.1 ticket必須加密,不加密則無法正常登錄】
應用場景
-
從第三方Portal打開協同
-
從第三方集成的協同欄目打開鏈接
關鍵步驟
下面描述了單點登錄的典型開發關鍵步驟,細節可參閱后續章節
- 配置外網訪問地址internet.site.url,如不配置,webService導出的數據的url為空
- 建立一個插件,作為單點登錄配置和Class的容器。參見本地開發接口的插件化章節。
建立握手類,例如
public class MySSOLoginHandshake extends SSOLoginHandshakeAbstract {
// “ticket” 就是ticket取得的參數值
public String handshake(String ticket) {
if(ticket==null||ticket.equals("")) {
return null;
}
HttpClient hc = new HttpClient();
//對應下圖(實現原理)中 步驟4:協同平臺與第三方系統握手,根據ticket獲取loginName
loginName = hc.get("http://第三方系統/getLoginIdByTicket?ticket="+ticket);
// 返回ticket對應的協同登錄名
return loginName;
}
public void logoutNotify(String ticket) {
HttpClient hc = new HttpClient();
//用戶退出協同時,通知第三方系統。
loginName = hc.get("http://第三方系統/logout?ticket="+ticket);
}
}
- 建立握手類Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="samplesso" class="com.seeyon.ctp.portal.sso.SSOLoginContext">
<property name="name" value="sample"/>
<property name="forward" value="true"/>
<property name="handshake">
<!-- 使用自己的握手實現 -->
<bean class="com.seeyon.apps.plugin.MySSOLoginHandshake" />
</property>
</bean>
</beans>
實現原理
從第三方系統登錄到協同,這種認證是完全信任第三方系統的,單點登錄有兩種效果:
- 單點登錄成功后直接打開協同主頁面(缺省模式)。
- 單點登錄成功后并不打開協同主頁面,平臺維護ticket信息和登錄用戶信息,為以后請求服務作認證使用。
比如:請求獲得協同待辦事項列表服務。需要配置SSOLoginContext.xml中一個屬性如下: 單點登錄的前提是外部系統使用和協同一致的登錄名或維護了兩個系統的登錄名映射,也就是說,外部系統必須知道它的當前用戶在協同中的登錄名。 請注意,為了安全,登錄過程必須由第三方系統的服務器發出,不允許第三方系統客戶端直接單點登錄。 登錄過程:
-
獲取當前用戶的ticket:
用戶登錄外部平臺,發出要訪問協同平臺的請求。
-
生成ticket:
外部平臺生成ticket,ticket不能為中文,也不能使用協同平臺的登錄名,最理想的ticket是類似sessionId的隨機字符串。并在第三方系統服務器中,記錄 ticket 和 ctp平臺中的loginName的關聯關系。
-
登錄:外部平臺帶著ticket、from(握手bean的name,如下文中的gke)和UserAgentFrom跳轉到協同平臺
UserAgentFrom是一個枚舉代表著不同端的登錄(默認值:pc)。 UserAgentFrom枚舉值如下: pc //pc端 phone //移動端 ucpc //ucpc wechat //微信端 登錄URL如下所示: /seeyon/login/sso?from=gke&ticket=ticket***&UserAgentFrom=pc
-
handshark 握手請求:
發起一個請求,從第三方系統中獲取ticket對應的loginName。
-
返回ticket對應loginName:
外部平臺將ticket對應的協同登錄名告知協同協同平臺。如果沒有獲取到loginName,表示握手失敗。
-
SSOOK:
平臺執行其他相關操作,完成ticket與用戶信息綁定的注冊(并在內存中存儲ticket和username映射)。在response header中增加SSOOK。
-
返回ticket
-
協同平臺通過ticket參數,調用登錄操作,完成用戶登錄
示例: /seeyon/main.do?method=login&ticket=[ticket]&ssoFrom=gke&UserAgentFrom=pc
-
定時發送心跳,保證用戶在線
各個端的心跳接口如下:
通用心跳接口(保持當前用戶登錄的端的心跳):/seeyon/getAJAXOnlineServlet?V=[隨機數] 通用心跳接口(保持當前用戶登錄的端的心跳):/seeyon/getAJAXOnlineServlet?V=[隨機數] 致信端心跳接口:/seeyon/uc/rest.do?method=showUpdateSystemHistoryMessages×tamp=[隨機數] M3端心跳接口: /seeyon/rest/m3/message/classification
退出過程:
- 用戶退出協同時,會通過SSOLoginHandshakeInterface的logoutNotify()通知到第三方系統
- 用戶退出第三方系統時,訪問協同平臺的/seeyon/login/ssologout?from=&ticket=&userAgentFrom**通知協同平臺** !!!重要,為了安全,必須logout。
接口說明:
- 外部平臺需要有協同登錄名的映射表或者使用相同的登錄名
- SSOLoginHandshakeInterface與from映射,需要配置或二次開發。
- 配置:系統提供通用的com.seeyon.ctp.portal.sso.SSOLoginHandshakeServletImpl,配置url(外部系統中傳入ticket返回協同登錄名的頁面地址)和logoutUrl即可。 二次開發:實現接口SSOLoginHandshakeAbstract,自己編寫握手邏輯,比如下面的GKEA8SSOLoginImpl。
- 平臺的驗證系統完全依賴和信任第三方系統(存在風險,因此,只在服務器之間握手至關重要)
配置文件說明:在插件的spring目錄增加xml配置文件
SSOLoginContext.xml示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="gke" class="com.seeyon.ctp.portal.sso.SSOLoginContext">
<property name="name" value="gke"/>
<!-- 單點登錄成功是否跳轉到首頁 -->
<property name="forward" value="false"/>
<!-- 握手配置 -->
<property name="handshake">
<!-- 使用系統實現的缺省握手類 -->
<bean class="com.seeyon.ctp.portal.sso.SSOLoginHandshakeServletImpl">
<!-- 第三方系統頁面,傳入ticket,返回協同登錄名 -->
<property name="url" value="http://第三方系統:8080/checkTicket"/>
<!-- 第三方系統頁面單點登錄登出地址 -->
<property name="logoutUrl" value="http://第三方系統:8080/ssologout"/>
</bean>
</property>
</bean>
</beans>
或
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="gke" class="com.seeyon.ctp.portal.sso.SSOLoginContext">
<property name="name" value="gke"/>
<property name="handshake">
<!-- 使用自己的握手實現 -->
<bean class="com.seeyon.v3x.plugin.gke.sso.GKEA8SSOLoginImp" />
</property>
</bean>
</beans>
二次開發需要實現SSOLoginHandshakeAbstract的handshake和logoutNotify方法
/**
* 通過握手獲取平臺的認證信息
* @param ticket 平臺傳過來的令牌信息
* @return 返回當前登錄者的登錄名
*/
public String handshake(String ticket);
/**
* A8退出時通知外部平臺
*
* @param ticket 平臺傳過來的令牌信息
*/
public void logoutNotify(String ticket);
代碼示例
從GKE登錄到協同平臺:
public class GKEA8SSOLoginImp extends SSOLoginHandshakeAbstract {
// “ticket” 就是ticket取得的參數值
public String handshake(String ticket) {
if(ticket==null||ticket.equals("")) {
return null;
}
String userName="";
// 這個是gke自己特定的ticket格式:{GID},{passport}
String[] r=ticket.split(",");
if(r==null||r.length!=2) {
return null;
}
userName=this.checkPassport(r[0], r[1]);
return userName;
}
public void logoutNotify(String ticket) {
}
private String checkPassport(String GID,String passPort) {
StringBuffer sb = new StringBuffer();
sb.append("<?xml version="1.0" encoding="UTF-8" ?>");
sb.append("<request type="login" subtype="passport" msid="">");
sb.append("<message>");
sb.append("<user");
sb.append(" GID=""+GID+"" gid="" zoneid="">");
sb.append("<passport>");
sb.append(passPort);
sb.append("</passport>");
sb.append("</user>");
sb.append("</message>");
sb.append("</request>");
// 向GKE發出請求,取得協同登錄名
return getGKEResponse(postGKERequest(sb.toString()));
}
單點登錄的URL包裝
單點登錄成功獲取Ticket以后,要想使用ticket訪問協同平臺內部地址,必須對URL進行包裝
String ticket = request.getParameter("ticket");
String url="collaboration/collaboration.do?method=summary&openFrom=listPending&affairId=-932843950278492";
TicketInfo ticketInfo = com.seeyon.ctp.portal.sso.SSOTicketBean.getTicketInfo(ticket);
if(ticketInfo != null) {
response.sendRedirect(com.seeyon.ctp.portal.sso.SSOTicketBean.makeURLOfSSOTicket(ticket, url));
}
示例:單點登錄+事項列表場景
-
通過單點登錄接口的tourl參數,直接登錄OA并且打開tourl對應OA地址頁面。
完整示例:
OA中某待辦協同地址: http://ip:端口/seeyon/collaboration/collaboration.do?method=summary&openFrom=listPending&affairId=-1036595126906172786 對應單點登錄URL: http://ip:端口/seeyon/login/sso?from=sample&ticket=lsm1&UserAgentFrom=pc&tourl=%2fseeyon%2fcollaboration%2fcollaboration.do%3Fmethod%3Dsummary%26openFrom%3DlistPending%26affairId%3D-1036595126906172786
從上面的示例中可以看出tourl是OA中具體鏈接的【/seeyon/collaboration/collaboration.do?method=summary&openFrom=listPending&affairId=-1036595126906172786】部分做了轉碼。
-
通過事項接口獲取列表URL后直接打開OA地址頁面。
看了上面的示例可能會有人問如何獲取OA中具體協同的打開地址呢?
現在OA平臺接口有2種方式可以獲取事項URL。
第一種方式:SOAP接口的exportPendingList方法:獲取待辦事項列表。這個接口需要要單點登錄成功以后才會導出事項 URL地址。
第二種方式:REST接口中【門戶集成】-【事項接口】(注意在V7.0版本,事項接口才可以導出URL地址),可以獲取事項的URL地址。
注意:通過以上兩種方式獲取到URL地址以后,必須要單點登錄成功以后,才能再請求獲取到的URL地址。而如果是通過tourl方式打開URL,則是單點登錄與打開URL同時請求,不需要單獨再做單點登錄請求。
其他:
部署說明:單點登錄的開發建立的java文件放在com.seeyon.ctp.portal.sso包下
跳轉到協同頁面
將協同頁面集成為第三方系統菜單項:
單點登錄以后,如果要實現在第三方系統打開協同平臺任意頁面的功能,可以使用下面的跳轉鏈接:
/seeyon/a8genius.do?method=window&url=xxx,
例如:
/seeyon/a8genius.do?method=window&url=calEvent.do%3Fmethod%3DhomeEntry
可以跳轉到協同平臺的日程計劃頁面/seeyon/calEvent.do?method= homeEntry 如果不進行跳轉,協同平臺頁面可能找不到依賴的javascript腳本,導致腳本錯誤,無法使用。
公司主要經營內容:
帆軟報表,帆軟軟件,致遠OA,北京致遠軟件,致遠軟件,致遠OA軟件,OA軟件,致遠OA辦公軟件,致遠OA協同軟件,OA協同軟件,OA辦公軟件,致遠辦公軟件,致遠協同辦公軟件,致遠OA協同辦公軟件,OA綜合辦公軟件,致遠系統,OA系統,致遠OA系統,北京致遠OA系統,北京致遠OA軟件,致遠OA系統軟件,致遠協同辦公系統,致遠協同辦公OA系統,致遠系統OA,致遠軟件OA,OA軟件系統,OA致遠北京,致遠A8OA,OAA8軟件,致遠A8軟件,致遠A8系統Oa軟件,致遠OA系統版本軟件