s-HR 单点登录及调OSF
调用s-HR的OSF接口必须先单点登录,目前有两种登录方式。下面描述两种登录方式,同时提供封装了两种登录方式的集成依赖包(下文附件中包含.net和php语言单点登录案例)
如果想自己开发一个不需要登录就可以调用的接口可参考:不需要登录就可以调用的接口开发(不推荐)
一、调用OSF
A. 单点登录配置
SSO数据中心:选中需要做单点登录的数据中心
登录认证器:此处仅供查看,目前s-HR提供通过OTP认证的单点登录认证方式
启用白名单拦截:勾选之后会启用白名单校验规则,如果第三方地址没有配置在白名单中可能会apusic拦截
白名单地址:在启用白名单之后,此处填写第三方地址,域名或者IP都可
webservice开启安全模式:支持会话粘贴,集群环境需要勾选保证webservice单点登录正常。
注意:配置修改完成之后需要重启服务才能生效。OTP认证配置是实时生效的
B.调用OSF接口
代码示例
import com.kingdee.shr.api.Response; import com.kingdee.shr.api.SHRClient; public class SSOTest{ public static void main(String[] args) throws Exception{ String SHR_LOCAL = "http://127.0.0.1:6888/shr"; //OSF名称,注意是名称不是编码 String serviceName = "getAccountService"; SHRClient client = new SHRClient(); //调用OSF所需要的参数 Map<String,Object> param = new HashMap<String,Object>(); Response res = client.executeService(SHR_LOCAL ,serviceName,param); System.out.println(res.getData()); } }
此处依赖shr_sso_client.jar
client.executeService()方法中已经默认封装好了登录、调用OSF和登出的方法,返回的res结果就是OSF的结果,所以不需要另外登录。该方法中默认使用了user用户做单点登录,所以系统中的user用户不能被禁用或者删除
如果想通过webservice调用OSF,需要确认s-HR是否已经部署了WSOSFWebserviceFacade?wsdl,可通过地址http://127.0.0.1:6888/ormrpc/services/WSOSFWebserviceFacade?wsdl确认。如果没有可部署下文附件中的私包。
webservice单点登录调用OSF代码示例
import com.kingdee.shr.api.OSFWSClient; import com.kingdee.shr.osf.webservice.client.UserInfo; public class SSOTest{ public static void main(String[] args) throws Exception{ String SHR_LOCAL = "http://127.0.0.1:6888/shr"; //OSF名称,注意是名称不是编码 String serviceName = "getAccountService"; //调用OSF所需要的参数 Map<String,Object> param = new HashMap<String,Object>(); OSFWSClient client = new OSFWSClient(); //webservice登录系统的用户信息 UserInfo userInfo=new UserInfo(); userInfo.setDcName("数据中心ID");//数据中心ID可在管理控制台中查看,为数据中心代码 userInfo.setLanguage("L2");//多语言,L1,L2,L3 userInfo.setUserName("username");//用户名 userInfo.setPassword("password");//用户密码 userInfo.setSlnName("eas");//固定值eas userInfo.setDbType(1);//数据库类型,0-SQL Server, 1-Oracle, 2-DB2 String res = client.proceedOSF(SHR_LOCAL,serviceName,param,userInfo); System.out.println(res); } }
此处依赖shr_osfws_client.jar
client.proceedOSF()方法中封装好了登录、调用OSF和登出的方法,res就是OSF的结果,不需要另外登录
webservice中还一种免密登录的方式,但是需要确认系统中是否存在这种登录方法,可通过地址http://127.0.0.1:6888/ormrpc/services/EASLogin?wsdl确认,查看是否存在loginByLtpaToken。
参考代码如下
import com.kingdee.shr.api.OSFWSClient; import com.kingdee.shr.osf.webservice.client.UserInfo; import com.kingdee.eas.cp.eip.sso.ltpa.LtpaTokenManager; public class SSOTest{ public static void main(String[] args) throws Exception{ String SHR_LOCAL = "http://127.0.0.1:6888/shr"; //OSF名称,注意是名称不是编码 String serviceName = "getAccountService"; //调用OSF所需要的参数 Map<String,Object> param = new HashMap<String,Object>(); OSFWSClient client = new OSFWSClient(); //webservice登录系统的用户信息 UserInfo userInfo=new UserInfo(); userInfo.setDcName("数据中心ID");//数据中心ID可在管理控制台中查看,为数据中心代码 userInfo.setLanguage("L2");//多语言,L1,L2,L3 userInfo.setUserName("username");//用户名 //配置文件路径,该配置文件需与s-HR服务端的一个配置文件内容保持一致,后续有详解 String configFile = "LtpaToken.properties";//configFile是指LtpaToken.properties配置文件的路径 //根据密钥生成的密码串 String password = LtpaTokenManager.generate("username",configFile).toString(); userInfo.setPassword(password);//生成的密码串 userInfo.setSlnName("eas");//固定值eas userInfo.setDbType();//数据库类型,0-SQL Server, 1-Oracle, 2-DB2 String res = client.proceedOSFByLtpa(SHR_LOCAL,serviceName,param,userInfo); System.out.println(res); } }
此处依赖shr_osfws_client.jar、kingdee_Ltpa.jar和LtpaToken.properties
client.proceedOSF()方法中封装好了登录、调用OSF和登出的方法,res就是OSF的结果,不需要另外登录
注意:此处的LtpaToken.properties文件必须与服务端{EAS-HOME}/eas/server/profiles/server(1-n)/config/portalConfig/LtpaToken.properties的配置文件中的domino.secret内容保持一致,这是生成密码的密钥串。如果是多个实例,每个实例的该文件都必须一致。
二、第三方页面跳转
A. 走EAS页面
参考地址:
http://127.0.0.1:6888/portal/index2sso.jsp?username=username&password=password&redirectTo=redirectTo
代码示例
import java.net.URLEncoder; import com.kingdee.eas.cp.eip.sso.ltpa.LtpaTokenManager; import com.kingdee.eas.cp.eip.sso.ltpa.LtpaToken; public class SSOTest{ public static void main(String[] args) throws Exception{ //s-HR地址 String SHR_LOCAL = "http://127.0.0.1:6888/shr/home.do"; //登录用户名 String username="user"; //配置文件路径,该配置文件需与s-HR服务端的一个配置文件内容保持一致,后续有详解 String configFile = "LtpaToken.properties";//configFile是指LtpaToken.properties配置文件的路径 //登录成功之后重定向的地址,需要编码一次 String redirectTo = URLEncoder.encode(SHR_LOCAL); //根据密钥生成的密码串 String password = LtpaTokenManager.generate(username,configFile).toString(); String url = "http://127.0.0.1:6888/portal/index2sso.jsp?username="+username+"&password="+password+"&redirectTo="+redirectTo; System.out.println(url); } }
此处依赖kingdee_Ltpa.jar和LtpaToken.properties
如果是多语言环境,需跳转到其他的语言环境,请在将url改成http://127.0.0.1:6888/portal/index2sso.jsp?locale=L2&username=username&password=password&redirectTo=redirectTo,增加参数locale,值可为L1、L2或L3
注意:此处的LtpaToken.properties文件必须与服务端{EAS-HOME}/eas/server/profiles/server(1-n)/config/portalConfig/LtpaToken.properties的配置文件中的domino.secret内容保持一致,这是生成密码的密钥串。如果是多个实例,每个实例的该文件都必须一致。
B.走s-HR页面
参考地址:
http://127.0.0.1:6888/shr/OTP2sso.jsp?username=username&password=password&userAuthPattern=OTP&isNotCheckRelogin=true&redirectTo=redirectTo
import java.net.URLEncoder; import com.kingdee.shr.sso.client.ltpa.LtpaTokenManager; public class SSOTest{ public static void main(String[] args) throws Exception{ //s-HR地址 String SHR_LOCAL = "http://127.0.0.1:6888/shr/home.do"; //登录用户名 String username="user"; //登录成功之后重定向的地址,需要编码一次 String redirectTo = URLEncoder.encode(SHR_LOCAL); //根据密钥生成的密码串 String password = LtpaTokenManager.generate(username,LtpaTokenManager.getDefaultLtpaConfig(), "OTP").toString(); String url = "http://127.0.0.1:6888/shr/OTP2sso.jsp?username="+username+"&password="+password+"&userAuthPattern=OTP&isNotCheckRelogin=true&redirectTo="+redirectTo; System.out.println(url); } }
此处依赖shr_sso_client.jar,jar包中包含配置文件LtpaToken.properties
如果是多语言环境,需跳转到其他的语言环境,请在将url改成http://127.0.0.1:6888/shr/OTP2sso.jsp?locale=L2&username=username&password=password&userAuthPattern=OTP&isNotCheckRelogin=true&redirectTo=redirectTo,增加参数locale,值可为L1、L2或L3
注意:此处的LtpaToken.properties文件必须与服务端{EAS-HOME}/eas/server/profiles/server(1-n)/config/portalConfig/LtpaToken.properties的配置文件中的otp.domino.secret内容保持一致,这是生成密码的密钥串。如果是多个实例,每个实例的该文件都必须一致。
web-demo压缩文件中提供了部署在第三方的页面,如果直接部署的话需要按以下操作完成基础配置,涉及到的主要文件列表如下:
配置文件:shr-ssoClient.properties
依赖的jar包:shr_sso_client.jar
jsp页面:loginhr.jsp、sso2hrUrl.jsp
js:shr.window.js
1. 修改文件shr-ssoClient.properties
#s-HR地址 server.url=http://127.0.0.1:6888 #这里是固定值,无需修改 server.path=/shr/OTP2sso.jsp #认证方式,默认为OTP,无需修改 auth.pattern=OTP #获取用户名的实现类全路径,下一步会描述 userNameBuilder=ssoShrLogin.ShrLogin
2. 实现com.kingdee.shr.sso.client.user.IUserNameBuilder接口,此处实现后在shr_sso_client.jar中是通过反射去获取用户名的,可通过shr_sso_client.jar中的com.kingdee.shr.sso.client.util.SSOUtil.getUserName()看到。
默认示例代码如下
import com.kingdee.shr.sso.client.user.IUserNameBuilder; public class DefaultUserNameBuilder implements IUserNameBuilder { public String getUserName(HttpServletRequest request) { //此处写从第三方获取登录s-HR用户名的逻辑,并返回用户名 Object userName = request.getSession().getAttribute("username"); return (String) (userName != null ? userName : request.getSession().getAttribute("userName")); } }
调试流程如下
loginhr.jsp-->shr.window.js-->sso2hrUrl.jsp-->com.kingdee.shr.sso.client.util.SSOUtil.generateUrl
.net和php调用OSF(包含webservice).zip
C# OTP方式源码
B、通过webservice调用OSF,总会报以下错误。
Call OSF error: ; nested exception is:
org.xml.sax.SAXException: Deserializing parameter 'loginByLtpaTokenReturn': could not find deserializer for type {urn:client}WSContext
{ "error": "Call OSF error: org.xml.sax.SAXException: Deserializing parameter 'loginByLtpaTokenReturn': could not find deserializer for type {urn:client}WSContext"}
Process finished with exit code 0
程序代码copy就是贴子以下的,修改了数据中心,用户名密码数据库等
SDK升级优化:
1、移除日志打印依赖org.slf4j.Logger(移除了依赖jarslf4j-api-1.7.32.jar)
2、SHRClient增加重载方法public Response executeService(String serverUrl, String serviceName, Map<String, Object> param, String userName),对低版本SDK的升级兼容
3、移除对axis.jar的StringUtils的依赖
最小的jar包依赖为:
commons-discovery-0.2.jar
gson-2.9.0.jar
httpclient-4.5.13.jar
httpcore-4.4.14.jar
httpmime-4.5.13.jar
javax.servlet-api-3.0.1.jar
javax.wsdl_1.6.2.v201012040545.jar
jaxrpc.jar
commons-logging-1.2.jar
你好,net的httpclient方式中,的tokenconfig.xml未提供,看代码需要提供一个pwd字段,该字段内容如何生成?
OTP单点登录报错,服务器日志堆栈如下,请检查SDK调用时生成password的类引用为com.kingdee.shr.sso.client.ltpa.LtpaTokenManager而非com.kingdee.eas.cp.eip.sso.ltpa.LtpaTokenManager,替换类引用即可:
2024-01-03 14:15:31 错误 [apusic.web.EASWeb./shr-Thread 314] 执行Servlet时发生错误。
java.lang.NegativeArraySizeException
at com.kingdee.eas.cp.eip.sso.shr.ltap.ShrLtpaToken.<init>(ShrLtpaToken.java:95)
at com.kingdee.eas.cp.eip.sso.shr.ltap.ShrLtpaTokenManager.isValid(ShrLtpaTokenManager.java:345)
at com.kingdee.eas.cp.eip.sso.otp.OTPAuthHandler.authenticate(OTPAuthHandler.java:67)
at com.kingdee.shr.guilogin.web.wechart.WeChartUtil.authenWechart(WeChartUtil.java:38)
提示”token已过期或不合法“就是服务端的密钥没有同步到调用方,检查秘钥是否对齐。调用方调试断点直接打在com.kingdee.shr.sso.client.ltpa.LtpaTokenManager#loadConfig(String)处,看到底读的是否修改后的密钥,若还是初始密钥。就是shr_sso_client.jar中的配置文件的密钥没改过来\src\main\java\com\kingdee\shr\sso\client\ltpa\LtpaToken.properties
为什么使用走s-HR页面的方法,生成的连接访问的时候使用中文,显示用户账号不能为空!
若HttpClient方式中文传输乱码,请使用最新SDK。
问题:webservice单点登录调用,未进行用户登出。
解决方案:更改webservice接口调用方式,com.kingdee.shr.api.OSFWSClient#proceedOSFAndLogout方法(此方法在接口调用完后会进行用户登出),替换com.kingdee.shr.api.OSFWSClient#proceedOSF
s-HR版本若为8.6.1.1版本,单点登录报错302重定向到首页,需要更新补丁PT163032
s-HR 单点登录及调OSF
本文2024-09-17 00:51:39发表“s-hr cloud知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-shr-63709.html
- 鼎捷EAI整合規範文件V3.1.07 (集團).pdf
- 鼎捷OpenAPI應用場景說明_基礎資料.pdf
- 鼎捷OpenAPI應用場景說明_財務管理.pdf
- 鼎捷T100 API設計器使用手冊T100 APIDesigner(V1.0).docx
- 鼎新e-GoB2雲端ERP B2 線上課程E6-2應付票據整批郵寄 領取.pdf
- 鼎新e-GoB2雲端ERP B2 線上課程A4使用者建立權限設定.pdf
- 鼎新e-GoB2雲端ERP B2 線上課程C3會計開帳與會計傳票.pdf
- 鼎新e-GoB2雲端ERP B2 線上課程E6-1應付票據.pdf
- 鼎新e-GoB2雲端ERP B2 線上課程A5-1進銷存參數設定(初階篇).pdf
- 鼎新e-GoB2雲端ERP B2 線上課程D2帳款開帳與票據開帳.pdf