Java接口说明

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) {

    }
}

2024-10-22
0 0