123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- package com.kingdee.eas.custom.sso;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.kingdee.bos.BOSException;
- import com.kingdee.bos.Context;
- import com.kingdee.eas.cp.eip.sso.ltpa.LtpaTokenManager;
- import com.kingdee.eas.cp.eip.sso.util.CASLoginConfigPropUtil;
- import com.kingdee.eas.cp.eip.sso.util.CloudParamUtil;
- import com.kingdee.eas.util.app.DbUtil;
- import com.kingdee.jdbc.rowset.IRowSet;
- import com.kingdee.shr.base.syssetting.exception.SHRWebException;
- import com.kingdee.util.StringUtils;
- import okhttp3.*;
- import org.apache.log4j.Logger;
- import javax.crypto.Cipher;
- import javax.crypto.SecretKey;
- import javax.crypto.spec.SecretKeySpec;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.*;
- import java.net.URLEncoder;
- import java.sql.SQLException;
- import java.util.*;
- /**
- * @Description OA单点sHR
- * @Date 2024/10/30 11:22
- * @Created by Heyuan
- */
- public class OAToSHR extends HttpServlet {
- private static Logger logger = Logger.getLogger(OAToSHR.class);
- private static ExpiringMapCache<String, String> redirectUrlCache = new ExpiringMapCache<>();
- private Properties prop = new Properties();
- private String propPath = System.getProperty("EAS_HOME") + "/server/properties/scy/OASSOConfig.properties";
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- logger.error("OAToSHR -> doGet");
- doPost(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- logger.error("OAToSHR -> doPost");
- BufferedReader streamReader = null;
- String resultStr = null;
- prop.load(new FileInputStream(propPath));
- logger.error("OAToSHR requestUrl" + req.getRequestURL().toString());
- try {
- String ticket = req.getParameter("ticket");
- logger.error("接收到的请求参数是:ticket " + ticket);
- if (StringUtils.isEmpty(ticket)) {
- //认证
- authorize(req, resp);
- } else {
- //获取用户信息
- callBack(req, resp, ticket);
- }
- } catch (Exception e) {
- e.printStackTrace();
- Map result = new HashMap();
- result.put("msgType", "0");
- result.put("reason", e.getMessage());
- resultStr = JSON.toJSONString(result);
- resp.setStatus(500);
- PrintWriter writer = resp.getWriter();
- resp.setContentType("application/json");
- writer.write(resultStr);
- writer.close();
- } finally {
- try {
- if (streamReader != null) {
- streamReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 认证
- * 拼接OA认证接口地址,转发
- *
- * @param resp
- * @throws Exception
- */
- public void authorize(HttpServletRequest req, HttpServletResponse resp) throws Exception {
- String authorizePath = prop.getProperty("authorizePath");
- if (StringUtils.isEmpty(authorizePath)) {
- throw new RuntimeException("authorizePath不能为空! 请检查配置文件: " + propPath);
- }
- String response_type = prop.getProperty("response_type");
- if (StringUtils.isEmpty(response_type)) {
- throw new RuntimeException("response_type不能为空! 请检查配置文件: " + propPath);
- }
- String client_id = prop.getProperty("client_id");
- if (StringUtils.isEmpty(client_id)) {
- throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
- }
- String redirect_uri1 = prop.getProperty("redirect_uri1");
- if (StringUtils.isEmpty(redirect_uri1)) {
- throw new RuntimeException("redirect_uri1不能为空! 请检查配置文件: " + propPath);
- }
- String redirectUrl = req.getParameter("redirect");
- if (StringUtils.isEmpty(redirectUrl)) {
- String serverName = prop.getProperty("serverName");
- if (StringUtils.isEmpty(serverName)) {
- throw new RuntimeException("serverName不能为空! 请检查配置文件: " + propPath);
- }
- redirectUrl = serverName + "/shr/dynamic.do?uipk=shr.perself.homepage";
- }
- Random random = new Random();
- String key = System.currentTimeMillis() + String.valueOf(random.nextInt(99999));
- redirectUrlCache.put(key, redirectUrl,300000);
- logger.error("callBack redirectUrl" + redirectUrl);
- redirect_uri1 += "?redirect=" + key;
- Map params = new HashMap();
- params.put("client_id", client_id);
- params.put("response_type", response_type);
- params.put("redirect_uri", URLEncoder.encode(redirect_uri1, "UTF-8"));
- String urlString = appendUrl(authorizePath, params);
- resp.sendRedirect(urlString);
- logger.error("authorize url" + urlString);
- }
- /**
- * OA回调方法
- * 获取Token和用户信息,单点到shr
- *
- * @param req
- * @param resp
- * @param ticket
- * @throws SHRWebException
- * @throws UnsupportedEncodingException
- */
- public void callBack(HttpServletRequest req, HttpServletResponse resp, String ticket) throws
- SHRWebException, UnsupportedEncodingException {
- logger.error("callback方法入参");
- if (StringUtils.isEmpty(ticket)) {
- throw new RuntimeException("ticket不能为空!");
- }
- String getAccessTokenPath = prop.getProperty("getAccessTokenPath");
- if (StringUtils.isEmpty(getAccessTokenPath)) {
- throw new RuntimeException("getAccessTokenPath不能为空! 请检查配置文件: " + propPath);
- }
- String client_secret = prop.getProperty("client_secret");
- if (StringUtils.isEmpty(client_secret)) {
- throw new RuntimeException("client_secret不能为空! 请检查配置文件: " + propPath);
- }
- String client_id = prop.getProperty("client_id");
- if (StringUtils.isEmpty(client_id)) {
- throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
- }
- String redirect_uri2 = prop.getProperty("redirect_uri2");
- if (StringUtils.isEmpty(redirect_uri2)) {
- throw new RuntimeException("redirect_uri2不能为空! 请检查配置文件: " + propPath);
- }
- String getLoginIdPath = prop.getProperty("getLoginIdPath");
- if (StringUtils.isEmpty(getLoginIdPath)) {
- throw new RuntimeException("getLoginIdPath不能为空! 请检查配置文件: " + propPath);
- }
- String redirectUrl = req.getParameter("redirect");
- logger.error("callBack redirectUrl" + redirectUrl);
- Map params = new HashMap();
- params.put("client_id", client_id);
- params.put("client_secret", client_secret);
- params.put("grant_type", "authorization_code");
- params.put("code", ticket);
- params.put("redirect_uri", URLEncoder.encode(redirect_uri2, "UTF-8"));
- try {
- String token = getAccessToken(getAccessTokenPath, params);
- logger.error(token);
- //从人员对象,获取纷享用户userId
- String loginId = loginId2userId(getLoginIdPath, token);
- String loginUrl = login(loginId, redirectUrl);
- resp.sendRedirect(loginUrl);
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e.getMessage());
- }
- }
- /**
- * 获取携带账号和密码的登录地址
- *
- * @param userNumber
- * @param redirectUrlKey
- * @return
- */
- private String login(String userNumber, String redirectUrlKey) throws Exception {
- String password = LtpaTokenManager.generate(userNumber, LtpaTokenManager.getDefaultLtpaConfig()).toString();
- logger.error("login: password" + password);
- String serverName = prop.getProperty("serverName");
- if (StringUtils.isEmpty(serverName)) {
- throw new RuntimeException("serverName不能为空! 请检查配置文件: " + propPath);
- }
- StringBuilder url = new StringBuilder();
- url.append("/shr/index2sso.jsp?username=").append(userNumber)
- .append("&password=").append(password).append("&redirectTo=");
- StringBuilder redirectUrlStr = new StringBuilder();
- if (StringUtils.isEmpty(redirectUrlKey)) {
- redirectUrlStr.append(serverName).append("/shr/dynamic.do?uipk=shr.perself.homepage");
- } else {
- String redirectUrl = redirectUrlCache.get(redirectUrlKey);
- if (redirectUrl.contains(serverName)) {
- redirectUrlStr.append(redirectUrl);
- } else {
- redirectUrlStr.append(serverName).append(redirectUrl);
- }
- }
- String encode = URLEncoder.encode(redirectUrlStr.toString(), "UTF-8");
- url.append(URLEncoder.encode(encode, "UTF-8"));
- logger.error("login: url" + url);
- return url.toString();
- }
- /**
- * 获取泛微token方法
- *
- * @param getAccessTokenPath
- * @param params
- * @return
- * @throws IOException
- */
- private String getAccessToken(String getAccessTokenPath, Map<String, String> params)
- throws IOException {
- logger.error("getAccessToken方法参数: " + params);
- String url = appendUrl(getAccessTokenPath, params);
- logger.error("access_token url" + url);
- OkHttpClient client = new OkHttpClient();
- Request request = new Request.Builder()
- .url(url)
- .get()
- .addHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001")
- .build();
- Response response = client.newCall(request).execute();
- if (response.isSuccessful()) {
- String string = response.body().string();
- JSONObject jsonObject = JSONObject.parseObject(string);
- String code = jsonObject.getString("code");
- if ("0".equals(code)) {
- String access_token = jsonObject.getString("access_token");
- logger.error("access_token " + access_token);
- return access_token;
- } else {
- throw new RuntimeException(jsonObject.getString("msg"));
- }
- } else {
- //网络超时
- throw new RuntimeException("获取token超时");
- }
- }
- /**
- * 获取用户信息
- *
- * @param accessToken
- * @return
- * @throws IOException
- * @throws BOSException
- * @throws SQLException
- */
- private String loginId2userId(String getLoginIdPath, String accessToken)
- throws IOException, BOSException, SQLException {
- if (StringUtils.isEmpty(accessToken)) {
- throw new RuntimeException("accessToken不能为空! ");
- }
- //获取第三方用户信息
- Map params = new HashMap();
- params.put("access_token", accessToken);
- String url = appendUrl(getLoginIdPath, params);
- logger.error("loginId2userId url" + url);
- OkHttpClient client = new OkHttpClient();
- Request request = new Request.Builder()
- .url(url)
- .get()
- .addHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001")
- .build();
- Response response = client.newCall(request).execute();
- if (response.isSuccessful()) {
- String string = response.body().string();
- JSONObject jsonObject = JSONObject.parseObject(string);
- String code = jsonObject.getString("code");
- if ("0".equals(code)) {
- JSONObject attributes = jsonObject.getJSONObject("attributes");
- //登录id
- String loginid = attributes.getString("loginid");
- String dataCenter = CASLoginConfigPropUtil.getDataCenter();
- String locale = CASLoginConfigPropUtil.getLocale();
- if (!StringUtils.isEmpty(dataCenter) && !StringUtils.isEmpty(locale)) {
- Context ctx = CloudParamUtil.getContext(dataCenter, locale, "administrator");
- String sql = "SELECT count(1) total FROM T_PM_USER WHERE fnumber=?";
- IRowSet rs = DbUtil.executeQuery(ctx, sql, new Object[]{loginid});
- int total = 0;
- if (rs.next()) {
- total = rs.getInt("total");
- }
- if (total <= 0) {
- logger.error("SHR找不到对应的用户, loginid:" + loginid);
- throw new RuntimeException("SHR找不到对应的用户, loginid: " + loginid);
- //("您无权限访问SHR系统,请联系管理员处理。")
- } else if (total > 1) {
- logger.error("SHR找到多个对应的用户, loginid:" + loginid);
- throw new RuntimeException("SHR找到多个对应的用户, loginid: " + loginid);
- //("您无权限访问SHR系统,请联系管理员处理。")
- } else {
- return loginid;
- }
- }
- logger.error("获取用户信息报错,数据中心没找到!");
- throw new RuntimeException("获取用户信息报错,数据中心没找到!");
- } else {
- logger.error(jsonObject.getString("msg"));
- throw new RuntimeException(jsonObject.getString("msg"));
- }
- } else {
- //网络超时
- logger.error("网络超时");
- throw new RuntimeException("网络超时");
- }
- }
- /**
- * 拼接地址参数
- */
- private static String appendUrl(String url, Map<String, String> data) {
- logger.error("appendUrl_url: " + url);
- logger.error("appendUrl_data: " + data);
- StringBuilder paramStr = new StringBuilder();
- for (String key : data.keySet()) {
- paramStr.append(key).append("=").append(data.get(key)).append("&");
- }
- paramStr.deleteCharAt(paramStr.lastIndexOf("&"));
- String str = url.contains("?") ? (url + "&" + paramStr) : (url + "?" + paramStr);
- logger.error("拼接后的地址为:" + str);
- return str;
- }
- }
|