package jnpf.implicit.request; import com.alibaba.fastjson.JSONObject; import jnpf.socials.enums.AuthDefaultSourceNew; import com.xkcoding.http.support.HttpHeader; import jnpf.constant.MsgCode; import jnpf.socials.utils.AuthSocialsUtil; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.enums.AuthUserGender; import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.request.AuthDefaultRequest; import me.zhyd.oauth.utils.HttpUtils; import me.zhyd.oauth.utils.UrlBuilder; import org.apache.commons.codec.binary.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URLEncoder; import java.util.Date; public class ImplicitDingTalkRequest extends AuthDefaultRequest{ public ImplicitDingTalkRequest(AuthConfig config) { super(config, AuthDefaultSourceNew.DINGTALK_ACCOUNT); } @Override public String authorize(String state) { return UrlBuilder.fromBaseUrl(this.source.authorize()) .queryParam("appid", this.config.getClientId()) .queryParam("redirect_uri", this.config.getRedirectUri()) .queryParam("response_type", "code") .queryParam("scope", "snsapi_auth") .queryParam("state", "STATE") .build(); } @Override public AuthToken getAccessToken(AuthCallback authCallback) { return AuthToken.builder() .code(authCallback.getCode()).build(); } @Override public AuthUser getUserInfo(AuthToken authToken) { String response = this.doGetUserByCode(authToken); JSONObject object = AuthSocialsUtil.checkResponse(response, this.source); if (object.get("user_info") != null) { JSONObject userInfo = (JSONObject) object.get("user_info"); AuthToken token = AuthToken.builder().openId(userInfo.getString("openid")).unionId(userInfo.getString("unionid")).build(); return AuthUser.builder().rawUserInfo(userInfo).uuid(userInfo.getString("unionid")).nickname(userInfo.getString("nick")) .username(object.getString("nick")).gender(AuthUserGender.UNKNOWN).source(this.source.toString()).token(token).build(); } else { throw new AuthException(MsgCode.OA024.get()); } } /** * 钉钉签名计算 * * @param time * @return */ private String getSignature(long time) { // 根据timestamp, appSecret计算签名值 String appSecret = this.config.getClientSecret(); // 根据timestamp, appSecret计算签名值 String stringToSign = "" + time; Mac mac = null; try { mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256")); byte[] signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8")); String signature = new String(Base64.encodeBase64(signatureBytes)); if ("".equals(signature)) { return ""; } String encoded = URLEncoder.encode(signature, "UTF-8"); return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F"); } catch (Exception e) { throw new RuntimeException(e); } } protected String doGetUserByCode(AuthToken authToken) { long time = new Date().getTime(); String signature = this.getSignature(time); String url = UrlBuilder.fromBaseUrl("https://oapi.dingtalk.com/sns/getuserinfo_bycode") .queryParam("accessKey", this.config.getClientId()) .queryParam("timestamp", time) .queryParam("signature", signature) .build(); JSONObject map = new JSONObject(); map.put("tmp_auth_code", authToken.getCode()); return (new HttpUtils(this.config.getHttpConfig())).post(url, map.toJSONString(), new HttpHeader().add("Content-Type", "application/json")).getBody(); } }