最新要闻

广告

手机

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

票房这么火爆,如何请视障人士“看”一场电影?

票房这么火爆,如何请视障人士“看”一场电影?

家电

世界视点!浙里办单点登陆、令牌获取用户信息

来源:博客园

原文链接:https://blog.csdn.net/qq_41441896/article/details/124636772

浙里办开发票据认证单点登陆、令牌获取用户信息(JAVA后端处理)  最近在搞浙里办开发,周边的人里都没人接触过,以至于自己摸索搞起来比较心累。浙里办单点登陆需要在IRS上走申请,审核流程通过后,和指定的老师对接就可以了。

ak、sk获取  组件申请审核通过后,组件申请提交人可以通过“公共应用组件系统-我申请的组件” https://csss.zj.gov.cn/verifyComList/applyNew 获取 AK/SK 信息。发送ak、sk、回调地址 还有系统名称给易和的老师,发送可以参考我的。


(资料图片仅供参考)

系统名称 XXXXXX系统正式环境回调地址(测试环境发测试的地址) https://mapi.zjzwfw.gov.cn/web/mgop/gov-open/zj/200XXXX676/reserved/index.htmlSecretKey XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAccessKey 8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX81234阅读接入文档  通过对文档的阅读,锁定到文档目录4.0.1的票据认证接口和4.2.3的根据令牌获取用户信息接口。

接口调用controller/** * 浙里办用户信息Controller * * @author xxxxxx * @date 2022/4/11 */

import com.ruoyi.common.constant.PipelineConstants;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.utils.StringUtils;import com.zjasm.zlb.service.IZlbClientService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.annotations.ApiParam;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;

@Api("浙里办用户信息")@RestController@RequestMapping("/zlb/client")public class ZlbClientController {

@Autowired private IZlbClientService zlbClientService;

private static final Logger logger = LoggerFactory.getLogger(ZlbClientController.class);

/** * 获取用户临时授权码authCode */ @ApiOperation(value = "获取用户登陆票据ticket", notes = "获取用户登陆票据ticket", httpMethod = "GET") @GetMapping("/getClientTicket/{ticket}") public AjaxResult getClientTicket( @ApiParam(name = "票据ticket", value = "获取用户登陆票据ticket", required = true) @PathVariable String ticket) { if (StringUtils.isEmpty(ticket) || "undefined".equals(ticket)) { return AjaxResult.error(PipelineConstants.MSG_ERROR_PARAMETER_WRONG); } logger.info("获取用户登陆票据ticket=" + ticket); return zlbClientService.getClientTicketCode(ticket); }

/* * 根据令牌获取用户详细信息 */ @ApiOperation(value = "根据令牌token获取用户详细信息", notes = "根据令牌token获取用户详细信息", httpMethod = "GET") @GetMapping("/getClientInfo/{token}") public AjaxResult getClientInfoByToken( @ApiParam(name = "令牌token", value = "需要获取的用户令牌token", required = true) @PathVariable String token) { if (StringUtils.isEmpty(token) || "undefined".equals(token)) { return AjaxResult.error(PipelineConstants.MSG_ERROR_PARAMETER_WRONG); } logger.info("用户令牌token=" + token); return zlbClientService.getClientInfoByToken(token); }

}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061IService接口import com.ruoyi.common.core.domain.AjaxResult;

/** * 浙里办身份认证 * * @author xxxxxx * @date 2022/4/14 */public interface IZlbClientService {

public AjaxResult getClientTicketCode(String ticket);

public AjaxResult getClientInfoByToken(String token);}1234567891011121314service实现类

import com.alibaba.fastjson.JSONObject;import com.ruoyi.common.constant.PipelineConstants;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.core.domain.entity.SysRole;import com.ruoyi.common.core.domain.entity.SysUser;import com.ruoyi.common.core.domain.model.LoginUser;import com.ruoyi.common.utils.sign.Md5Utils;import com.ruoyi.framework.web.service.TokenService;import com.ruoyi.system.mapper.SysRoleMapper;import com.zjasm.zlb.model.ZlbClientInfo;import com.zjasm.zlb.model.ZlbTicketClientInfo;import com.zjasm.zlb.service.IZlbClientService;import com.zjasm.zlb.utils.HmacAuthUtil;import com.zjasm.zlb.utils.HttpUtil;import org.apache.http.client.methods.HttpPost;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;

import javax.annotation.Resource;import java.text.SimpleDateFormat;import java.util.*;

/** * 浙里办用户认证Service * * @author xxxxxx * @date 2022/4/14 */@Servicepublic class ZlbClientServiceImpl implements IZlbClientService {

/** * token验证处理 */ @Resource private TokenService tokenService; /** * 用户角色表处理 */ @Resource private SysRoleMapper sysRoleMapper;

/** * 初始密钥(仅正式ak和sk,没有测试ak和sk) */ private static final String ACCESS_KEY = "8******************************8"; private static final String APP_SECRET = "0******************************e";

/** * 接口请求 */ private final HttpUtil httpUtil = HttpUtil.getInstance(); /** * 日志打印 */ private static final Logger logger = LoggerFactory.getLogger(ZlbClientServiceImpl.class);

/** * 票据认证 * * @param ticket 票据 * @return 用户认证信息 */ @Override public AjaxResult getClientTicketCode(String ticket) { String url = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220228000002/sso/servlet/simpleauth"; // 接口请求方法 String method = "POST"; // 封装请求参数 Map header = HmacAuthUtil.generateHeader(url, method, ACCESS_KEY, APP_SECRET); // 创建POST请求 HttpPost httpPost = new HttpPost(url); Iterator its = header.keySet().iterator(); while (its.hasNext()) { String next = its.next(); httpPost.addHeader(next, header.get(next)); } // 拼接请求参数 Map params = new HashMap(20); String time = getSecondTimestamp(); params.put("servicecode", ACCESS_KEY); params.put("method", "ticketValidation"); // 时间戳,当前时间 params.put("time", time); // MD5(servicecode+servicepwd+time)参数servicepwd为组件平台的SecretKey params.put("sign", Md5Utils.hash(ACCESS_KEY + APP_SECRET + time)); // 票据 params.put("st", ticket); // 返回数据类型 params.put("datatype", "json"); String result = httpUtil.sendHttpPost(httpPost, params); logger.info("浙里办用户认证接口请求结果:" + result); JSONObject resultJson = JSONObject.parseObject(result); // 请求结果 String resultCode = resultJson.getString("result"); /** 自定义处理结果 ticket失效:{"result":"6001","errmsg":"st已经超时失效"}请求成功:{"result":"0","errmsg":"成功","token":"8a118xxxx7435-commonToken","userid":"8a118a4xxxxxxx414b84473","loginname":"xxxxxx","orgcoding":"xxxxxx","username":"xxx"} */ return null; }

@Override public AjaxResult getClientInfoByToken(String token) { String url = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220228000004/sso/servlet/simpleauth"; // 接口请求方法 String method = "POST"; // 封装请求参数 Map header = HmacAuthUtil.generateHeader(url, method, ACCESS_KEY, APP_SECRET); // 创建POST请求 HttpPost httpPost = new HttpPost(url); Iterator its = header.keySet().iterator(); while (its.hasNext()) { String next = its.next(); httpPost.addHeader(next, header.get(next)); } // 拼接请求参数 Map params = new HashMap(20); String time = getSecondTimestamp(); params.put("servicecode", ACCESS_KEY); params.put("method", "getUserInfo"); // 时间戳,当前时间 params.put("time", time); // MD5(servicecode+servicepwd+time)参数servicepwd为组件平台的SecretKey params.put("sign", Md5Utils.hash(ACCESS_KEY + APP_SECRET + time)); // 票据 params.put("token", token); // 返回数据类型 params.put("datatype", "json"); String result = httpUtil.sendHttpPost(httpPost, params); logger.info("浙里办用户认证接口请求结果:" + result); JSONObject resultJson = JSONObject.parseObject(result); // 请求结果 String resultCode = resultJson.getString("result"); if (PipelineConstants.MSG_INFO_ZLB_STATUS_SUCCESS.equals(resultCode)) { // 根据token获取用户信息 ZlbClientInfo zlbClientInfo = JSONObject.parseObject(result, ZlbClientInfo.class); logger.info("根据token获取用户信息ZlbClientInfo:" + zlbClientInfo.toString()); return AjaxResult.success(zlbClientInfo); } return AjaxResult.error(resultCode); }

/** * 获取时间戳,当前时间(年月日时分秒) * * @return 时间戳,当前时间(年月日时分秒)例如:2009年10月10日 12时12分12秒格式为20091010121212 */ private static String getSecondTimestamp() { // 时间戳,当前时间(年月日时分秒) SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); return formatter.format(new Date()); }

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157utils工具类HmacAuthUtil.javaimport javafx.util.Pair;import lombok.extern.slf4j.Slf4j;

import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import javax.xml.bind.DatatypeConverter;import java.io.UnsupportedEncodingException;import java.net.URI;import java.net.URL;import java.net.URLEncoder;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.*;import java.util.stream.Collectors;

/** * 浙里办加密工具类 */@Slf4jpublic class HmacAuthUtil {

/** * 构造请求 header * * @param urlStr 请求url,全路径格式,比如:https://bcdsg.zj.gov.cn/api/p/v1/user.get * @param requestMethod 请求方法,大写格式,如:GET, POST * @param accessKey 应用的 AK * @param secretKey 应用的 SK * @return */ public static Map generateHeader(String urlStr, String requestMethod, String accessKey, String secretKey) { log.info("params,urlStr={},requestMethod={},accessKey={},secretKey={}", urlStr, requestMethod, accessKey, secretKey); Map header = new HashMap<>(); try { DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); String date = dateFormat.format(new Date()); URL url = new URL(urlStr); URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);

String canonicalQueryString = getCanonicalQueryString(uri.getQuery());

String message = requestMethod.toUpperCase() + "\n" + uri.getPath() + "\n" + canonicalQueryString + "\n" + accessKey + "\n" + date + "\n";

Mac hasher = Mac.getInstance("HmacSHA256"); hasher.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"));

byte[] hash = hasher.doFinal(message.getBytes());

// to lowercase hexits DatatypeConverter.printHexBinary(hash);

// to base64 String sign = DatatypeConverter.printBase64Binary(hash); header.put("X-BG-HMAC-SIGNATURE", sign); header.put("X-BG-HMAC-ALGORITHM", "hmac-sha256"); header.put("X-BG-HMAC-ACCESS-KEY", accessKey); header.put("X-BG-DATE-TIME", date); } catch (Exception e) { log.error("generate error", e); throw new RuntimeException("generate header error"); } log.info("header info,{}", header); return header; }

private static String getCanonicalQueryString(String query) { if (query == null || query.trim().length() == 0) { return ""; } List> queryParamList = new ArrayList<>(); String[] params = query.split("&"); for (String param : params) { int eqIndex = param.indexOf("="); String key = param.substring(0, eqIndex); String value = param.substring(eqIndex + 1); Pair pair = new Pair(key, value); queryParamList.add(pair); }

List> sortedParamList = queryParamList.stream().sorted(Comparator.comparing(param -> param.getKey() + "=" + Optional.ofNullable(param.getValue()).orElse(""))).collect(Collectors.toList()); List> encodeParamList = new ArrayList<>(); sortedParamList.stream().forEach(param -> { try { String key = URLEncoder.encode(param.getKey(), "utf-8"); String value = URLEncoder.encode(Optional.ofNullable(param.getValue()).orElse(""), "utf-8") .replaceAll("\\%2B", "%20") .replaceAll("\\+", "%20") .replaceAll("\\%21", "!") .replaceAll("\\%27", """) .replaceAll("\\%28", "(") .replaceAll("\\%29", ")") .replaceAll("\\%7E", "~") .replaceAll("\\%25", "%"); encodeParamList.add(new Pair<>(key, value)); } catch (UnsupportedEncodingException e) { throw new RuntimeException("encoding error"); } }); StringBuilder queryParamString = new StringBuilder(64); for (Pair encodeParam : encodeParamList) { queryParamString.append(encodeParam.getKey()).append("=").append(Optional.ofNullable(encodeParam.getValue()).orElse("")); queryParamString.append("&"); }

return queryParamString.substring(0, queryParamString.length() - 1); }}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109HttpUtil.javaimport org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.DefaultHostnameVerifier;import org.apache.http.conn.util.PublicSuffixMatcher;import org.apache.http.conn.util.PublicSuffixMatcherLoader;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;

import java.io.IOException;import java.net.URL;import java.util.ArrayList;import java.util.List;import java.util.Map;

public class HttpUtil {

private final Logger logger = LoggerFactory.getLogger(getClass());

private final RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(8000) .setConnectTimeout(8000) .setConnectionRequestTimeout(8000) .build();

private static HttpUtil instance = null;

private HttpUtil() { }

public static HttpUtil getInstance() { if (instance == null) { instance = new HttpUtil(); } return instance; }

/** * 发送 post请求 * * @param httpUrl 地址 */ public String sendHttpPost(String httpUrl) { HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost return sendHttpPost(httpPost); }

/** * 发送 post请求 * * @param httpUrl 地址 * @param params 参数(格式:key1=value1&key2=value2) */ public String sendHttpPost(String httpUrl, String params) { HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost try { //设置参数 StringEntity stringEntity = new StringEntity(params, "UTF-8"); stringEntity.setContentType("application/x-www-form-urlencoded"); httpPost.setEntity(stringEntity); } catch (Exception e) { logger.error(e.getMessage(), e); } return sendHttpPost(httpPost); }

/** * 发送 post请求 * * @param httpUrl 地址 * @param maps 参数 */ public String sendHttpPost(String httpUrl, Map maps) { HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列 List nameValuePairs = new ArrayList(); for (String key : maps.keySet()) { nameValuePairs.add(new BasicNameValuePair(key, maps.get(key))); } try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); } catch (Exception e) { logger.error(e.getMessage(), e); } return sendHttpPost(httpPost); }

/** * 发送 post请求 * * @param httpPost 地址 * @param maps 参数 */ public String sendHttpPost(HttpPost httpPost, Map maps) { // 创建参数队列 List nameValuePairs = new ArrayList(); for (String key : maps.keySet()) { nameValuePairs.add(new BasicNameValuePair(key, maps.get(key))); } try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); } catch (Exception e) { logger.error(e.getMessage(), e); } return sendHttpPost(httpPost); }

/** * 发送Post请求 * * @param httpPost * @return */ private String sendHttpPost(HttpPost httpPost) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; try { // 创建默认的httpClient实例. httpClient = HttpClients.createDefault(); httpPost.setConfig(requestConfig); // 执行请求 response = httpClient.execute(httpPost); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { try { // 关闭连接,释放资源 if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (IOException e) { logger.error(e.getMessage(), e); } } return responseContent; }

/** * 发送 get请求 * * @param httpUrl */ public String sendHttpGet(String httpUrl) { HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求 return sendHttpGet(httpGet); }

/** * 发送 get请求Https * * @param httpUrl */ public String sendHttpsGet(String httpUrl) { HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求 return sendHttpsGet(httpGet); }

/** * 发送Get请求 * * @param httpGet * @return */ public String sendHttpGet(HttpGet httpGet) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; try { // 创建默认的httpClient实例. httpClient = HttpClients.createDefault(); httpGet.setConfig(requestConfig); // 执行请求 response = httpClient.execute(httpGet); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { try { // 关闭连接,释放资源 if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (IOException e) { logger.error(e.getMessage(), e); } } return responseContent; }

/** * 发送Get请求Https * * @return */ private String sendHttpsGet(HttpGet httpGet) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; try { // 创建默认的httpClient实例. PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString())); DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher); httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build(); httpGet.setConfig(requestConfig); // 执行请求 response = httpClient.execute(httpGet); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { try { // 关闭连接,释放资源 if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (IOException e) { logger.error(e.getMessage(), e); } } return responseContent; }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250实体类票据认证用户信息DTO ZlbTicketClientInfo.java/** * 票据认证用户信息DTO * * @author xxxxx * @date 2022/5/6 */public class ZlbTicketClientInfo {

/** 用户在SSO分配的身份唯一号 */ private String userId;

/** 用户真实姓名 */ @Excel(name = " 用户真实姓名") private String userName;

/** 用户昵称 */ @Excel(name = "登录用户名") private String loginname;

// 用户身份认证标识 private String sign;

// 令牌 private String token;

/*** getter&setter ***/}123456789101112131415161718192021222324252627浙里办用户信息对象VO ZlbClient.java/** * 浙里办用户信息对象VO * * @author xxxxx * @date 2022-05-06 */public class ZlbClient{ private static final long serialVersionUID = 1L;

/** 用户在SSO分配的身份唯一号 */ private String userId;

/** 认证级别 1.匿名 2.实名 3.实人 (当认证级别为2或者3的时候实名信息才有效) */ private String authlevel;

/** 用户真实姓名 */ @Excel(name = " 用户真实姓名") private String userName;

/** 用户昵称 */ @Excel(name = "登录用户名") private String loginname;

/** 证件号码(身份证) */ @Excel(name = "证件号码") private String idnum;

/** 用户性别(1男 2女) */ @Excel(name = "用户性别", readConverterExp = "1=男,2=女") private String sex;

/** 民族 */ @Excel(name = "民族") private String nation;

/** 用户邮箱 */ @Excel(name = "用户邮箱") private String email;

/** 手机号码 */ @Excel(name = "手机号码") private String mobile;

/** 邮编 */ @Excel(name = "邮编") private String postcode;

/** CA证书KEY */ @Excel(name = "CA证书KEY") private String cakey;

/** 生日 */ @Excel(name = "生日") private String birthday;

/** 国籍 */ @Excel(name = "国籍") private String country;

/** 省籍 */ @Excel(name = "省籍") private String province;

/** 城市 */ @Excel(name = "城市") private String city;

/** 办公地址 */ @Excel(name = "办公地址") private String officeaddress;

/** 办公电话 */ @Excel(name = "办公电话") private String officephone;

/** 办公传真 */ @Excel(name = "办公传真") private String officefax;

/** 家庭电话 */ @Excel(name = "家庭电话") private String homephone;

/** 家庭地址 */ @Excel(name = "家庭地址") private String homeaddress;

/** 头像路径 */ @Excel(name = "头像路径") private String headpicture;

/** 帐号状态:0正常,1禁用 */ @Excel(name = "帐号状态:0正常,1禁用") private String status;

/*** getter&setter ***/}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899pom文件MAVEN引入的Jar包比较多,这里简单列举几个必须的。

org.apache.httpcomponents httpclient 4.5.13

org.projectlombok lombok 1.16.10 provided 1234567891011121314前端参考前端的代码就不再列举了,可以参考

https://blog.csdn.net/Xiang_Gong_Ya_/article/details/121991249

关键词: 当前时间 用户认证 请求参数