LDAP是轻量目录访问协议(LightweightDirectory Access Protocol)的缩写,LDAP标准实际上是在X.500标准基础上产生的一个简化版本。
AD是Active Directory的缩写,AD是LDAP的一个应用实例,而不应该是LDAP本身。比如:windows域控的用户、权限管理应该是微软公司使用LDAP存储了一些数据来解决域控这个具体问题,只是AD顺便还提供了用户接口,也可以利用ActiveDirectory当做LDAP服务器存放一些自己的东西而已。
需求描述:SAP中的HR数据,比如用户姓名,手机号,邮箱地址,员工照片等,创建或者修改后需要同步更新到AD域服务器,用户登录windows操作系统后可以查看是否更新成功。
通信连接配置
LDAP前期配置需BASIS事先做好,执行LDAP事务码可以正常登录到AD目录。
连接器LDAP_HRO_500是一个RFC目标,通过SM59创建。详细的配置参数如下:
通过点击系统用户可以设置登录的用户:
LDAP账号密码需要设置:
LDAP连接器:
LDAP服务器:
通过查找功能可以查看AD库里的数据:
维护查询条件,注意格式:
执行LDAPMAP事务码,进行字段匹配。
· 1 筛选,用于查找SAP中的唯一数据
· 2 导入映射,设置筛选字段时需要设置此字段,用户查找AD域中的数据
· 3 导入映射,用于设置是否写入AD域字段
· 4 创建数据库,在SAP端生成新数据
· 5 创建LDAP,在AD端生成新数据
· 6 RDN,相对识别名称映射,本次传输的数据未使用到,但是系统程序里会校验这个字段,没有打勾的话会报错,此处只是有字段匹配被勾选,但是程序里未传输此字段的值
USERNAME– BAPIBNAME是必输项,但是本次场景中AD没有与其匹配的字段,所以将AD库中的主键值字段mail在此处匹配,程序里赋值的时候将邮箱地址赋值给BAPIBNAME。
执行数据传输
此次场景HR数据传输是定制化的字段,可以通过自开发程序来发送数据。通过SE19人员主数据的增强HRPAD00INFTY来将有变动的人员号写入自定义表,然后通过执行自开发程序发起数据同步。
自定义表ZHRLDAP_PERNR,与系统表HRLDAP_PERNR结构一样。
SE19中增强代码将需要同步的人员ID信息更新到上面的自定义表中。新建报表程序,取上表中人员数据发送到AD域。
*&---------------------------------------------------------------------**& Report Z01HRI0026*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*REPORT z01hri0026.*----------------------------------------------------------------------* type*----------------------------------------------------------------------TYPES: BEGIN OF ts_ldap_attr_l, pernr LIKE lda_attr_l-pernr, attr_tab LIKE lda_attr_l-attr_tab, attr_field LIKE lda_attr_l-attr_field, value LIKE lda_attr_l-value, END OF ts_ldap_attr_l.*----------------------------------------------------------------------* table*----------------------------------------------------------------------DATA: gt_ldap TYPE TABLE OF Zhrldap_pernr, gt_0001 TYPE TABLE OF pa0001, gt_0105 TYPE TABLE OF pa0105.*----------------------------------------------------------------------* work area*----------------------------------------------------------------------DATA: gw_ldap TYPE Zhrldap_pernr, gw_0001 TYPE pa0001, gw_0105 TYPE pa0105.*----------------------------------------------------------------------* data*----------------------------------------------------------------------DATA: gv_error TYPE c.*----------------------------------------------------------------------* screen*----------------------------------------------------------------------SELECT-OPTIONS: s_date FOR sy-datum.PARAMETERS: p_del TYPE c AS CHECKBOX.*----------------------------------------------------------------------* START-OF-SELECTION*----------------------------------------------------------------------START-OF-SELECTION. IF p_del IS INITIAL.* 取需要同步的数据 PERFORM frm_data_get.* 编辑并同步数据 PERFORM frm_data_send. ELSE. DELETE FROM Zhrldap_pernr WHERE AEDTM in s_date and PROCESSED = 'X'. ENDIF.*&---------------------------------------------------------------------**& Form FRM_DATA_GET*&---------------------------------------------------------------------**& text*&---------------------------------------------------------------------**& --> p1 text*& *&---------------------------------------------------------------------*FORM frm_data_get . SELECT * FROM Zhrldap_pernr INTO TABLE gt_ldap WHERE processed = '' AND aedtm in s_date. CHECK gt_ldap IS NOT INITIAL. SELECT pernr bukrs orgeh plans zzbz FROM pa0001 INTO CORRESPONDING FIELDS OF TABLE gt_0001 FOR ALL ENTRIES IN gt_ldap WHERE pernr = gt_ldap-pernr AND begda <= sy-datum AND endda >= sy-datum. SELECT * FROM pa0105 INTO CORRESPONDING FIELDS OF TABLE gt_0105 FOR ALL ENTRIES IN gt_ldap WHERE pernr = gt_ldap-pernr AND begda <= sy-datum AND endda >= sy-datum. SORT gt_0105 BY subty begda DESCENDING.ENDFORM.*&---------------------------------------------------------------------**& Form FRM_DATA_SEND*&---------------------------------------------------------------------**& 编辑并同步数据*&---------------------------------------------------------------------*FORM frm_data_send . DATA: attributes TYPE ts_ldap_attr_l OCCURS 0, attributes_wa TYPE ts_ldap_attr_l, lv_time TYPE i, lv_deptn TYPE string, lv_photo TYPE string, lv_objid TYPE hrp1001-objid, logsys LIKE tbdls-logsys, ldapsrv LIKE lda_types-ldapserver, errors LIKE bapiret2 OCCURS 0, errors_wa LIKE bapiret2. DATA: mid TYPE sy-msgid VALUE 'LDAPSYNC', mtype TYPE sy-msgty VALUE 'I', num TYPE sy-msgno. LOOP AT gt_ldap INTO gw_ldap. attributes_wa-pernr = gw_ldap-pernr.* attributes_wa-attr_tab = 'EMPLOYEE'.* attributes_wa-attr_field = 'KEY'.** attributes_wa-value = gw_0105-usrid.* APPEND attributes_wa TO attributes. "邮件、手机号、SAP账号 CLEAR gw_0105. READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0006'. IF gw_0105-usrid IS NOT INITIAL. attributes_wa-attr_tab = 'USERNAME'. attributes_wa-attr_field = 'BAPIBNAME'. attributes_wa-value = gw_0105-usrid. APPEND attributes_wa TO attributes. else. CONTINUE. ENDIF. CLEAR gw_0105. READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0004'. IF gw_0105-usrid IS NOT INITIAL. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'MOBILE'. attributes_wa-value = gw_0105-usrid. APPEND attributes_wa TO attributes. ENDIF. CLEAR gw_0105. READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0001'. IF gw_0105-usrid IS NOT INITIAL. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'BNAME'. attributes_wa-value = gw_0105-usrid. APPEND attributes_wa TO attributes. ENDIF. "同步公司、组织单位、职位 CLEAR gw_0001. READ TABLE gt_0001 INTO gw_0001 WITH KEY pernr = gw_ldap-pernr. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'PERNR'. attributes_wa-value = gw_0001-pernr. APPEND attributes_wa TO attributes. "公司 SELECT SINGLE butxt FROM t001 INTO @DATA(lv_butxt) WHERE bukrs = @gw_0001-bukrs. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'COMPANY'. attributes_wa-value = lv_butxt. APPEND attributes_wa TO attributes. CLEAR lv_butxt. "职务 if gw_0001-zzbz is INITIAL. SELECT SINGLE stext FROM hrp1000 INTO @DATA(lv_stext) WHERE plvar = '01' AND otype = 'S' AND objid = @gw_0001-plans AND istat = '1' AND begda <= @sy-datum AND endda >= @sy-datum AND langu = '1'. else. lv_stext = gw_0001-zzbz. endif. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'TITLE'. attributes_wa-value = lv_stext. APPEND attributes_wa TO attributes. CLEAR lv_stext. "部门 lv_objid = gw_0001-orgeh. "先检查当前条,不符合条件则检索上一级的组织 CLEAR: lv_time,lv_deptn. IF lv_objid IS NOT INITIAL. DO 10 TIMES. lv_time = lv_time + 1. SELECT SINGLE * FROM hrp9503 INTO @DATA(lw_9503) WHERE otype = 'O' AND objid = @lv_objid AND begda <= @sy-datum AND endda >= @sy-datum. IF sy-subrc = 0. "取到组织单位 SELECT SINGLE * FROM hrp1000 INTO @DATA(lw_1000) WHERE otype = 'O' AND objid = @lv_objid AND begda <= @sy-datum AND endda >= @sy-datum. IF lw_9503-zznsjgcj = '2'. lv_deptn = lw_1000-mc_stext. ELSEIF lw_9503-zznsjgcj = '1'. IF lv_deptn IS INITIAL. lv_deptn = lw_1000-mc_stext. ELSE. CONCATENATE lw_1000-mc_stext lv_deptn INTO lv_deptn. ENDIF. EXIT. ENDIF. ENDIF. "检索上一级组织 SELECT SINGLE * FROM hrp1001 INTO @DATA(lw_1001) WHERE otype = 'O' AND objid = @lv_objid AND rsign = 'A' AND relat = '002' AND begda <= @sy-datum AND endda >= @sy-datum. IF sy-subrc = 0. lv_objid = lw_1001-sobid. ENDIF. CLEAR: lw_9503,lw_1000,lw_1001. ENDDO. ENDIF. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'DEPARTMENT'. attributes_wa-value = lv_deptn. APPEND attributes_wa TO attributes. CLEAR lv_deptn.* 取员工照片 PERFORM frm_get_photo USING gw_ldap-pernr CHANGING lv_photo. attributes_wa-attr_tab = 'EMPLOYEE'. attributes_wa-attr_field = 'PHOTO'. attributes_wa-value = lv_photo. APPEND attributes_wa TO attributes. CLEAR lv_photo. ENDLOOP.* send attributes to ldap client logsys = 'LDAP_HRQ_500'. ldapsrv = 'AD_SINOCHEM'.* send attributes CALL FUNCTION 'SPLDAP_RECEIVE_ATTRIBUTES' EXPORTING logsys = logsys serverid = ldapsrv* ATTRIBUTES_S = attributes[]* initial_run = ldapinitialrun attributes_l = attributes[]* ATTRIBUTES_X = TOTAL_ATTRS_X[]. IMPORTING return = errors[]. IF NOT errors[] IS INITIAL. READ TABLE errors INDEX 1 INTO errors_wa. MESSAGE ID errors_wa-id TYPE errors_wa-type NUMBER errors_wa-number WITH errors_wa-message_v1 errors_wa-message_v2 errors_wa-message_v3 errors_wa-message_v4. else. MESSAGE ID mid TYPE mtype NUMBER 022. gw_ldap-PROCESSED = 'X'. modify gt_ldap FROM gw_ldap TRANSPORTING PROCESSED WHERE PROCESSED = ''. modify Zhrldap_pernr FROM TABLE gt_ldap. commit WORK. ENDIF.ENDFORM.*&---------------------------------------------------------------------**& Form FRM_GET_PHOTO*&---------------------------------------------------------------------**& 取员工照片*&---------------------------------------------------------------------**& --> LS_PA_REQUEST_PERNR*& *&---------------------------------------------------------------------*FORM frm_get_photo USING pv_pernr CHANGING pv_photo. DATA: ls_image_info TYPE toav0, lv_image_exists(1) TYPE c, lv_len TYPE i, lv_pos TYPE i, lv_time TYPE i, lt_mime TYPE TABLE OF W3MIME, lv_content TYPE XSTRING, lv_pernr TYPE p0001-pernr, lt_data LIKE TABLE OF tbl1024, lw_data like tbl1024.* 以下用于取照片 CLEAR: ls_image_info, lv_len, lt_data, lv_image_exists. lv_pernr = pv_pernr."'20600010'. "2、员工照片 CALL FUNCTION 'HR_IMAGE_EXISTS' EXPORTING p_pernr = lv_pernr p_tclas = 'A' p_begda = sy-datum p_endda = sy-datum IMPORTING p_exists = lv_image_exists p_connect_info = ls_image_info EXCEPTIONS error_connectiontable = 1 OTHERS = 2. IF sy-subrc = 0. CALL FUNCTION 'SCMS_AO_TABLE_GET' EXPORTING arc_id = ls_image_info-archiv_id doc_id = ls_image_info-arc_doc_id IMPORTING length = lv_len TABLES data = lt_data EXCEPTIONS error_http = 1 error_archiv = 2 error_kernel = 3 error_config = 4 OTHERS = 5. IF sy-subrc = 0. LOOP AT lt_data INTO lw_data.. pv_photo = pv_photo && lw_data-LINE. ENDLOOP. exit. CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' EXPORTING input_length = lv_len IMPORTING buffer = lv_content TABLES binary_tab = lt_data EXCEPTIONS failed = 1 OTHERS = 2. pv_photo = lv_content.* CALL FUNCTION 'RSFO_XSTRING_TO_MIME'* EXPORTING* C_XSTRING = lv_content* I_LENGTH = lv_len* TABLES* C_T_MIME = lt_MIME. ENDIF. ELSE.* CLEAR GV_GLAG.* GV_GLAG = 'X'.* EXIT. ENDIF.ENDFORM.