ios账号第三方登录,判断是否是Ios账号

  import com.alibaba.fastjson.JSONArray;

  import com.alibaba.fastjson.JSONObject;

  import com.rrk.common.center.bin.exception.RrkException;

  import com.rrk.common.center.tool.http.HttpUtils;

  import io.jsonwebtoken.Claims;

  import io.jsonwebtoken.Jws;

  import io.jsonwebtoken.JwtParser;

  import io.jsonwebtoken.Jwts;

  import org.apache.commons.codec.binary.Base64;

  import org.apache.commons.lang3.StringUtils;

  import org.slf4j.Logger;

  import org.slf4j.LoggerFactory;

  import java.math.BigInteger;

  import java.security.KeyFactory;

  import java.security.PublicKey;

  import java.security.spec.RSAPublicKeySpec;

  public class AppleAuthUtils {

  private static final Logger LOG = LoggerFactory.getLogger(AppleAuthUtils.class);
  private static final String AUTH_URL = "https://appleid.apple.com/auth/keys";
/**
 * 验证授权信息是否有效
 *
 * @param identityToken
 * @param appleAccount
 * @return
 */

public static boolean verify(String identityToken, String appleAccount) {
    String[] identityData = StringUtils.split(identityToken, ".");
    if (identityData.length == 0) {
        return false;
    }
    try {
        String headStr = new String(Base64.decodeBase64(identityData[0]), "utf-8");
        JSONObject headData = JSONObject.parseObject(headStr);
        // 公钥id标识
        String kid = headData.getString("kid");
        String identityStr = new String(Base64.decodeBase64(identityData[1]), "utf-8");
        JSONObject data = JSONObject.parseObject(identityStr);
        System.out.println(data);
        // 对比iOS客户端传过来的用户唯一标识是否和授权凭证一致
        if (!appleAccount.equals(data.getString("sub"))) {
            LOG.info("Apple登录授权用户信息不一致");
            throw new RrkException("Apple登录授权用户信息不一致");
        }
        JwtParser jwtParser = Jwts.parser().setSigningKey(AppleAuthUtils.buildAuthPublicKey(kid));
        jwtParser.requireIssuer(data.getString("iss"));
        // iOS应用标识
        jwtParser.requireAudience(data.getString("aud"));
        // 用户的唯一标识
        jwtParser.requireSubject(data.getString("sub"));
        Jws<Claims> claims = jwtParser.parseClaimsJws(identityToken);
        if (claims != null && claims.getBody().containsKey("auth_time")) {
            return true;
        }
    } catch (Exception e) {
        LOG.error("验证Apple登录授权信息失败,原因:", e);
        throw new RrkException("验证Apple登录授权信息过期");

    }
    return false;
}

public static String getEmail(String identityToken, String appleAccount) {
    String[] identityData = StringUtils.split(identityToken, ".");
    if (identityData.length == 0) {
        return "";
    }
    try {
        String identityStr = new String(Base64.decodeBase64(identityData[1]), "utf-8");
        JSONObject data = JSONObject.parseObject(identityStr);
        return data.get("email").toString();
    } catch (Exception e) {
        LOG.error("验证Apple登录授权信息失败,原因:", e);
        throw new RrkException("验证Apple登录授权信息过期");
    }
}

/**
 * 生成授权公钥
 *
 * @return
 */
private static PublicKey buildAuthPublicKey(String kid) {
    try {
        // 调用苹果接口获取公钥参数
        String jsonStr =HttpUtils.get(AUTH_URL).getBody();

        if (StringUtils.isEmpty(jsonStr)) {
            return null;
        }
        JSONObject result = JSONObject.parseObject(jsonStr);
        JSONArray keys = result.getJSONArray("keys");
        if (keys == null || keys.size() == 0) {
            return null;
        }
        JSONObject currentKey = null;
        // 通常情况下返回值keys包含2个,需要根据kid来决定使用哪套公钥参数
        for (int i = 0; i < keys.size(); i++) {
            JSONObject key = keys.getJSONObject(i);
            if (kid.equals(key.getString("kid"))) {
                currentKey = key;
                break;
            }
        }
        if (currentKey == null) {
            return null;
        }
        String n = currentKey.getString("n");
        String e = currentKey.getString("e");
        BigInteger modulus = new BigInteger(1, Base64.decodeBase64(n));
        BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(e));
        RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    } catch (Exception e) {
        LOG.error("生成Apple登录授权公钥出错,原因:", e);
    }
    return null;
}
posted @ 2020-11-24 13:36  优优鱼  阅读(128)  评论(0编辑  收藏  举报