最近在搞浙里办开发,周边的人里都没人接触过,以至于自己摸索搞起来比较心累。浙里办单点登陆需要在IRS上走申请,审核流程通过后,和指定的老师对接就可以了。
组件申请审核通过后,组件申请提交人可以通过“公共应用组件系统-我申请的组件” 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.html
SecretKey XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AccessKey 8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX8
阅读接入文档
通过对文档的阅读,锁定到文档目录4.0.1的票据认证接口和4.2.3的根据令牌获取用户信息接口。
/**
* 浙里办用户信息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);
}
}
IService接口
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);
}
service实现类
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
*/
@Service
public 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<String, String> header = HmacAuthUtil.generateHeader(url, method, ACCESS_KEY, APP_SECRET);
// 创建POST请求
HttpPost httpPost = new HttpPost(url);
Iterator<String> its = header.keySet().iterator();
while (its.hasNext()) {
String next = its.next();
httpPost.addHeader(next, header.get(next));
}
// 拼接请求参数
Map<String, String> params = new HashMap<String, String>(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<String, String> header = HmacAuthUtil.generateHeader(url, method, ACCESS_KEY, APP_SECRET);
// 创建POST请求
HttpPost httpPost = new HttpPost(url);
Iterator<String> its = header.keySet().iterator();
while (its.hasNext()) {
String next = its.next();
httpPost.addHeader(next, header.get(next));
}
// 拼接请求参数
Map<String, String> params = new HashMap<String, String>(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());
}
utils工具类
- HmacAuthUtil.java
import 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;
/**
* 浙里办加密工具类
*/
@Slf4j
public 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<String, String> generateHeader(String urlStr, String requestMethod, String accessKey, String secretKey) {
log.info("params,urlStr={},requestMethod={},accessKey={},secretKey={}", urlStr, requestMethod, accessKey, secretKey);
Map<String, String> 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<Pair<String, String>> 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<String, String> pair = new Pair<String, String>(key, value);
queryParamList.add(pair);
}
List<Pair<String, String>> sortedParamList = queryParamList.stream().sorted(Comparator.comparing(param -> param.getKey() + "=" + Optional.ofNullable(param.getValue()).orElse(""))).collect(Collectors.toList());
List<Pair<String, String>> 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<String, String> encodeParam : encodeParamList) {
queryParamString.append(encodeParam.getKey()).append("=").append(Optional.ofNullable(encodeParam.getValue()).orElse(""));
queryParamString.append("&");
}
return queryParamString.substring(0, queryParamString.length() - 1);
}
}
- HttpUtil.java
import 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<String, String> maps) {
HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
// 创建参数队列
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
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<String, String> maps) {
// 创建参数队列
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
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;
}
}
pom文件
MAVEN引入的Jar包比较多,这里简单列举几个必须的。
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>4.5.13version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.10version>
<scope>providedscope>
dependency>
前端参考
前端的代码就不再列举了,可以参考
https://blog.csdn.net/Xiang_Gong_Ya_/article/details/121991249
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)