package fx.custom.apl.example.custom_oauth_protocol;
import com.fxiaoke.functions.FunctionContext;
import com.fxiaoke.functions.Fx;
import com.fxiaoke.functions.http.FormBody;
import com.fxiaoke.functions.http.HttpResult;
import com.fxiaoke.functions.http.Request;
import com.fxiaoke.functions.model.APIResult;
import com.fxiaoke.functions.model.FQLAttribute;
import com.fxiaoke.functions.model.QueryResult;
import com.fxiaoke.functions.service.oauth.AuthProviderPlugin;
import com.fxiaoke.functions.utils.Maps;
import java.util.List;
import java.util.Map;
import static com.fxiaoke.functions.Fx.*;
/**
* 单点登录对接蓝凌OA标准模板
* 修改模板函数中的变量后可以直接使用
*/
class AuthProviderExample implements AuthProviderPlugin {
//蓝凌接口地址前缀-必填 SSO 地址
private static String PREFIX_URL = "第三方单点登录地址";
//应用ID-必填 OAuth client_id
private static String CLIENTID = "";
//应用密钥-必填 OAuth client_secret
private static String CLIENTSECRET = "";
//蓝凌OA关键字与纷享人员字段上的映射关系
private static String Mapping_Field = "employee_number";
//管理后台申请的单点登录域名
private static String Domain = "";
//当前这个函数的函数名
private static String FunctionName = "";
//纷享回调地址-必填 访问地址
private static String redirect_uri = "https://" + Domain + ".my.fxiaoke.com/oauth/sp/callback/" + FunctionName;
private static String logoffUrl = "https://" + Domain + ".my.fxiaoke.com/oauth/sp/logout/" + FunctionName;
/**
* 登录时打开 {租户域名}.my.fxiaoke.com 跳转的第三方url
*/
@Override
public String authorize(FunctionContext context, Map<String, List<String>> params) {
APIResult apiResult = Fx.crypto.getURL().encode(redirect_uri);
// def( boolean error, String reuslt, String errorMessage) =Fx.crypto.getURL().encode(redirect_uri);
log.info("redirect_uri == " + redirect_uri);
log.info("reusltUrl == " + apiResult.getData());
log.info("跳转idp登录url--context:" + context);
final Map<String, String> param = Maps.of(
"client_id", CLIENTID,
"redirect_uri", String.valueOf(apiResult.getData()),
"response_type", "code"
);
return appendUrl(PREFIX_URL + "/oauth2.0/authorize", param);
}
/**
* 第三方登录完成后的回调函数,一般用于获取用户信息
*
* @param params 第三方回调时,URL的参数
* @return 返回纷享系统的员工ID
*/
@Override
public Integer callback(FunctionContext context, Map<String, List<String>> params) {
log.info("callback_context: " + context);
log.info("callback_params: " + params);
//租户临时授权模式,如果有其他模式,请阅读第三方文档
String token = getAccessToken(params);
log.info("token: " + token);
//从人员对象,获取纷享用户userId
Integer userId = openId2userId(token);
log.info("userId: " + userId);
return userId;
}
/**
* 登录成功后打开的页面,可以从params获取,或者指定一个页面,空则是打开默认的页面
*
* @return 登录成功后打开的URL
*/
@Override
public String redirect(FunctionContext context, Map<String, List<String>> params) {
return "";
}
/**
* 在纷享系统登出时,自动跳转到第三方系统登出地址
*
* @return 第三方登录地址,如无需登出第三方,请返回null
*/
@Override
public String logoffUrl(FunctionContext context) {
return logoffUrl;
}
/**
* URL回调
*/
private static String appendUrl(String url, Map<String, String> data) {
log.info("appendUrl_url: " + url);
log.info("appendUrl_data: " + data);
String paramStr = "";
for (Map.Entry<String, String> entry : data.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
paramStr += key + "=" + value + "&";
}
paramStr = paramStr.substring(0, paramStr.length() - 1);
String str = url.contains("?") ? (url + "&" + paramStr) : (url + "?" + paramStr);
log.info("STR:" + str);
return str;
}
String getAccessToken(Map<String, List<String>> parameterMap) {
log.info("getAccessToken_parameterMap: " + parameterMap);
//以某第三方为示意,具体请查看第三方登录文档
FormBody body = FormBody.builder()
.field("client_id", CLIENTID)
.field("grant_type", "authorization_code")
.field("client_secret", CLIENTSECRET)
.field("code", parameterMap.get("code").get(0))
.build();
Request request = Request.builder()
.method("POST")
.url(PREFIX_URL + "/oauth2.0/accessToken")
.timeout(7000)
.retryCount(0)
.body(body)
.build();
HttpResult o = (HttpResult) http.execute(request).getData();
log.info(o);
return ((Map) o.getContent()).get("access_token").toString();
}
Integer openId2userId(String accessToken) {
//获取第三方用户信息
log.info("accessToken " + accessToken);
HttpResult o = (HttpResult) http.get(PREFIX_URL + "/oauth2.0/profile?access_token=" + accessToken).getData();
log.info("o === " + o);
String user = ((Map) o.getContent()).get("id").toString();
log.info("user ===" + user);
// 从第三方用户信息里,查询人员对象获取绑定信息,建议用自定义字段
QueryResult data = (QueryResult) object.find("PersonnelObj", FQLAttribute.builder().build()).getData();
List<Map> dataList = data.getDataList();
// 如果用户信息查找失败,返回错误
// 也可以在此根据信息,进行新建人员并且设置绑定字段的内容
if (dataList.size() <= 0) {
log.info("找不到对应的用户, user:" + user);
message.throwErrorMessage("CRM找不到您的账号,请联系管理员处理。");
}
if (dataList.size() > 1) {
log.info("找不到对应的用户, user:" + user);
message.throwErrorMessage("CRM找不到您的账号,请联系管理员处理。");
}
// 返回员工对象中的user_id字段,用于后续登录时使用
return (Integer) dataList.get(0).get("user_id");
}
public static void main(String[] args) {
}
}
Java接口说明
2024-10-22