前言
整个认证实现过程时序图
1、前端页面
注意调试时必须在蓝信的客户端中调试,否则蓝信的js会报错;
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<title></title>
<!--引入蓝信的js库-->
<script type="text/javascript" src="js/app-jssdk.umd.min.js" charset="utf-8"></script>
<script type="text/javascript" src="js/jquery-1.7.2.min.js" charset="utf-8"></script>
<script type="text/javascript" src="js/vconsole.min.js" charset="utf-8"></script>
<script type="text/javascript" src="js/wn_lanxinapp.js" charset="utf-8"></script>
</head>
<body>
</body>
</html>
<script type="text/javascript">
let appId = getPropValue("lanXinConfig", "lanXinAppId")
var vConsole = new window.VConsole();
jQuery().ready(function () {
lx.biz.getAuthCode({
appId: appId,
success: function (res) {
console.log("res", res);
const {
authCode} = res;
let oaResult = getOAToken(authCode);
console.log("oaResult", oaResult);
if (oaResult.code == 0) {
window.location.replace("/spa/portal/static4em/index.html?ssoToken=" + oaResult.token + "#/main");
} else {
alert(oaResult.msg);
}
},
fail: function (err) {
console.log("getAuthCode err", err);
},
});
})
</script>
wn_lanxinapp.js ,调用后端方法ajax封装
//用于获取配置文件的值
function getPropValue(propname, fieldname) {
var result = '';
jQuery.ajax({
url: '/weavernorth/lx/propajax.jsp?poopname=' + propname + '&fieldname=' + fieldname,
dataType: "text",
contentType: "charset=utf-8",
error: function (ajaxrequest) {
},
async: false,
success: function (data) {
result = jQuery.trim(data);
}
});
return result;
}
//获取最终的OA的ssoToken
function getOAToken(authCode) {
var params = "code=" + authCode;
var result;
jQuery.ajax({
type: "GET",
data: params,
dataType: "text",
url: "/api/sso/lanXin",
async: false,
success: function (data) {
result = JSON.parse(data);
},
error: function () {
console.log("获取OAToken异常,请联系管理员!");
}
});
return result;
}
2、/api/sso/lanXin 的web层代码
@GET
@Path("/lanXin")
@Produces(MediaType.APPLICATION_JSON)
public JSONObject lanXinSingleSignOn(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {
JSONObject result = new JSONObject();
HashMap<String, String> tokenMap = new HashMap<>();
// 蓝信附带信息
String code = Util.null2String(request.getParameter("code"));
log.info("前端传入code:{}" + code);
User user = (User) request.getSession(true).getAttribute("weaver_user@bean");
log.info("当前OA用户user:{}" + JSON.toJSON(user));
// 获取用户信息
JSONObject userInfo = new JSONObject();
if (user == null) {
if ("".equals(code)) {
result.put("code", 1);
result.put("msg", "获取蓝信code失败!");
return result;
}
// 获取应用访问token
String accessToken = lanXinSingleSignOnService().getAccessToken();
log.info("getAccessToken:{}" + accessToken);
if ("".equals(accessToken)) {
result.put("code", 1);
result.put("msg", "调用蓝信应用token接口失败!");
return result;
}
// 获取人员访问token
String userToken = lanXinSingleSignOnService().getUserToken(accessToken, code);
log.info("蓝信用户token:{}" + userToken);
if ("".equals(userToken)) {
result.put("code", 1);
result.put("msg", "调用蓝信用户token接口失败!");
return result;
}
// 获取用户信息
userInfo = lanXinSingleSignOnService().getUserInfo(accessToken, userToken);
log.info("蓝信用户信息:{}" + userInfo);
if (userInfo == null) {
result.put("code", 1);
result.put("msg", "获取蓝信用户信息失败!请检查OA是否存在此用户,并且手机号是否一致");
return result;
}
} else {
JSONObject data = new JSONObject();
data.put("mobile", user.getLoginid());
userInfo.put("code", 0);
userInfo.put("data", data);
userInfo.put("msg", "success");
}
String token = oASingleSignOnService().getOaToken(userInfo);
if ("".equals(token)) {
result.put("code", 1);
result.put("msg", "获取OA系统token失败");
return result;
}
result.put("code", 0);
result.put("msg", "获取oaToken成功!");
result.put("token", token);
result.put("mobile", userInfo.getJSONObject("data").getStr("mobile"));
return result;
}
3、获取蓝信的accesstoken
@Override
public String execute(CommandContext commandContext) {
//蓝信地址
String address = Prop.getPropValue("lanXinConfig", "lanXinAddress");
// 应用ID, 创建应用时取得
String appId = Prop.getPropValue("lanXinConfig", "lanXinAppId");
// 应用对应的AppSecret, 创建应用时取得
String appSecret = Prop.getPropValue("lanXinConfig", "lanXinAppSecret");
String url = address + "/v1/apptoken/create?grant_type=client_credential" +
"&appid=" + appId + "&secret=" + appSecret;
log.info("获取应用token接口:" + url);
String resultString = HttpRequest.get(url).execute().body();
log.info("获取应用token返回信息:{}" + resultString);
Result<JSONObject> result = JSONObject.parseObject(resultString, Result.class);
if (result.getErrCode() == 0) {
JSONObject data = result.getData();
return data.getString("appToken");
}
String errMsg = result.getErrMsg();
log.error("获取蓝信应用token失败:{}" + errMsg);
return "";
}
4、获取蓝信usertoken
@Override
public String execute(CommandContext commandContext) {
// 蓝信地址
String address = Prop.getPropValue("lanXinConfig", "lanXinAddress");
// 获取用户token接口
String url = address + "/v1/usertoken/create?app_token=" + getAccessToken() + "&grant_type=authorization_code&" +
"code=" + getCode();
log.info("获取蓝信用户token接口:{}" + url);
String resultString = HttpRequest.get(url).execute().body();
log.info("获取蓝信用户token接口返回数据:{}" + resultString);
Result<JSONObject> result = JSONObject.parseObject(resultString, Result.class);
if (result.getErrCode() == 0) {
String userToken = result.getData().getString("userToken");
return userToken;
}
String errMsg = result.getErrMsg();
log.error("获取蓝信用户token失败:{}" + errMsg);
return "";
}
5、获取蓝信用户信息
@Override
public JSONObject execute(CommandContext commandContext) {
JSONObject returnData = new JSONObject();
// 蓝信地址
String address = Prop.getPropValue("lanXinConfig", "lanXinAddress");
// 获取人员信息接口
String url = address + "/v1/users/fetch?app_token=" + getAccessToken() + "&user_token=" + getUserToken();
log.info("获取蓝信人员信息接口:{}" + url);
String resultString = HttpRequest.get(url).execute().body();
log.info("获取蓝信用户信息接口返回数据:{}" + resultString);
if (JSONUtil.isJsonObj(resultString)) {
JSONObject result = JSONUtil.parseObj(resultString);
if (result.getInt("errCode") == 0) {
String number = result.getJSONObject("data").getJSONObject("mobilePhone").getStr("number");
JSONObject data = new JSONObject();
data.put("mobile", number);
returnData.put("code", 0);
returnData.put("data", data);
returnData.put("msg", "success");
}
} else {
returnData.put("code", "1");
returnData.put("msg", "蓝信返回数据报文格式异常");
}
return returnData;
}