需要的jar包:

jose4j-0.6.4.jar;jwks-rsa-0.9.0.jar;jjwt-0.9.1.jar;

jar包下载地址:https://download.csdn.net/download/loveLF1314/12270178

package com.cctin.platform.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;

import java.security.PublicKey;
import java.util.Base64;
import java.util.List;
import java.util.Map;

import org.jose4j.jws.JsonWebSignature;
import org.jose4j.lang.JoseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.auth0.jwk.InvalidPublicKeyException;
import com.auth0.jwk.Jwk;

public class JwtUtils {

private static String getAppleIdPublicKeyFromRemote() {

ResponseEntity<String> responseEntity = new RestTemplate().getForEntity("https://appleid.apple.com/auth/keys", String.class);
        if (responseEntity == null || responseEntity.getStatusCode() != HttpStatus.OK) {
            return null;
        }
        return responseEntity.getBody();
    }

private static PublicKey getAppleIdPublicKey(String kid) {
        String publicKeyStr = getAppleIdPublicKeyFromRemote();
        return publicKeyAdapter(publicKeyStr, kid);
    }

/**
     * 将appleServer返回的publicKey转换成PublicKey对象
     * 
     * @param publicKeyStr
     * @return
     */
    private static PublicKey publicKeyAdapter(String publicKeyStr, String kid) {
        if (!StringUtils.hasText(publicKeyStr)) {
            return null;
        }
        Map maps = (Map) JSON.parse(publicKeyStr);
        List<Map> keys = (List<Map>) maps.get("keys");
        Map o = null;
        for (Map key : keys) {
            if (kid.equals(key.get("kid"))) {
                o = key;
                break;
            }
        }
        if(null != o){
            Jwk jwa = Jwk.fromValues(o);
            try {
                PublicKey publicKey = jwa.getPublicKey();
                return publicKey;
            } catch (InvalidPublicKeyException e) {
                e.printStackTrace();
                return null;
            }
        }else{
            return null;
        }
        
    }

public static boolean verify2(PublicKey key, String jwt, String audience, String subject) {
        JwtParser jwtParser = Jwts.parser().setSigningKey(key);
        jwtParser.requireIssuer("https://appleid.apple.com");
        jwtParser.requireAudience(audience);
        jwtParser.requireSubject(subject);
        try {
            Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
            if (claim != null && claim.getBody().containsKey("auth_time")) {
                return true;
            }
            return false;
        } catch (ExpiredJwtException e) {
            return false;
        } catch (Exception e) {
            return false;
        }
    }
    /**
     * 
     * @Title: isValid
     * @Description: TODO(校验基本信息:nonce,iss,aud,exp)   
     * @param accessToken
     * @return
     * boolean
     */
    public static boolean isValid(String accessToken) {
        CusJws cusJws = getJws(accessToken);
        if (cusJws == null) {
            return false;
        }
        // iss
        long curTime = System.currentTimeMillis();
        if (cusJws.getJwsPayload().getExp() * 1000 < curTime) {
            return false;
        }
        if (!JwsPayload.ISS.equals(cusJws.getJwsPayload().getIss())) {
            return false;
        }
        // 校验签名
        PublicKey publicKey = getAppleIdPublicKey(cusJws.getJwsHeader().getKid());
        if (!verifySignature(accessToken, publicKey)) {
            return false;
        }
        if(!verify2(publicKey, accessToken, cusJws.getJwsPayload().getAud(), cusJws.getJwsPayload().getSub())){
            return false;
        }
        return true;
    }

/**
     * verify signature
     * 
     * @param accessToken
     * @return
     */
    private static boolean verifySignature(String accessToken, PublicKey publicKey) {
        JsonWebSignature jsonWebSignature = new JsonWebSignature();
        jsonWebSignature.setKey(publicKey);
        try {
            jsonWebSignature.setCompactSerialization(accessToken);
            return jsonWebSignature.verifySignature();
        } catch (JoseException e) {
            return false;
        }
    }

private static CusJws getJws(String identityToken) {
        String[] arrToken = identityToken.split("\\.");
        if (arrToken == null || arrToken.length != 3) {
            return null;
        }
        Base64.Decoder decoder = Base64.getDecoder();
        JwsHeader jwsHeader = JSON.parseObject(new String(decoder.decode(arrToken[0])), JwsHeader.class);
        JwsPayload jwsPayload = JSON.parseObject(new String(decoder.decode(arrToken[1])), JwsPayload.class);
        return new CusJws(jwsHeader, jwsPayload, arrToken[2]);
    }

static class CusJws {
        private JwsHeader jwsHeader;
        private JwsPayload jwsPayload;
        private String signature;

public CusJws(JwsHeader jwsHeader, JwsPayload jwsPayload, String signature) {
            this.jwsHeader = jwsHeader;
            this.jwsPayload = jwsPayload;
            this.signature = signature;
        }

public JwsHeader getJwsHeader() {
            return jwsHeader;
        }

public void setJwsHeader(JwsHeader jwsHeader) {
            this.jwsHeader = jwsHeader;
        }

public JwsPayload getJwsPayload() {
            return jwsPayload;
        }

public void setJwsPayload(JwsPayload jwsPayload) {
            this.jwsPayload = jwsPayload;
        }

public String getSignature() {
            return signature;
        }

public void setSignature(String signature) {
            this.signature = signature;
        }
    }

static class JwsHeader {
        private String kid;
        private String alg;

public String getKid() {
            return kid;
        }

public void setKid(String kid) {
            this.kid = kid;
        }

public String getAlg() {
            return alg;
        }

public void setAlg(String alg) {
            this.alg = alg;
        }
    }

static class JwsPayload {
        private String iss;
        private String sub;
        private String aud;
        private long exp;
        private long iat;
        private String nonce;
        private String email;
        private boolean email_verified;

public final static String ISS = "https://appleid.apple.com";

public String getIss() {
            return iss;
        }

public void setIss(String iss) {
            this.iss = iss;
        }

public String getSub() {
            return sub;
        }

public void setSub(String sub) {
            this.sub = sub;
        }

public String getAud() {
            return aud;
        }

public void setAud(String aud) {
            this.aud = aud;
        }

public long getExp() {
            return exp;
        }

public void setExp(long exp) {
            this.exp = exp;
        }

public long getIat() {
            return iat;
        }

public void setIat(long iat) {
            this.iat = iat;
        }

public String getNonce() {
            return nonce;
        }

public void setNonce(String nonce) {
            this.nonce = nonce;
        }

public String getEmail() {
            return email;
        }

public void setEmail(String email) {
            this.email = email;
        }

public boolean isEmail_verified() {
            return email_verified;
        }

public void setEmail_verified(boolean email_verified) {
            this.email_verified = email_verified;
        }
    }    
}

苹果授权登陆 服务端验证(java)相关推荐

  1. postman关闭ssl验证_【第5期】springboot:苹果内购服务端验证

    ​苹果内购: 只要你在苹果系统购买APP中虚拟物品(虚拟货币,VIP充值等),必须通过内购方式进行支付,苹果和商家进行三七开 验证模式有两种: Validating Receipts With the ...

  2. golang 苹果登录,服务端验证identityToken(真实有效)

    介绍 2019年之后,对于Apple App来说,如果要支持第三方登录,则必须同时支持苹果的第三方登录,即Sign in With Apple, 本文主要介绍如何使用Go语言实现Sign in Wit ...

  3. Sign in with Apple(苹果授权登陆) java jwt方式验证

    本文章借鉴的原文链接:https://blog.csdn.net/wpf199402076118/article/details/99677412 苹果授权登陆方式 PC/M端授权登陆,采用协议类似于 ...

  4. Sign in with Apple(苹果授权登陆)

    苹果授权登陆方式 1. PC/M端授权登陆,采用协议类似于oauth2协议 2. App端授权登陆,提供两种后端验证方式 开发者后台配置 详细配置参考该文档,手把手教学 https://develop ...

  5. Sign in with Apple(苹果授权登陆)服务端验证-测试通过版

    Sign in with Apple(苹果授权登陆)服务端验证-测试通过版 1.先引用2个jwt用到的jar包 2.算法的工具类 三方登录调用验证工具类 苹果登录方式有2种,这里介绍基于JWT算法验证 ...

  6. java服务端验证谷歌支付Google Pay

    翻阅大半个谷歌,对服务器验证账单,讲的少之又少,还TM没有看懂 查阅整个百度,发现几乎所有demo都是用世界上最好的语言php写的,这我 在此坐下记录希望能帮到有需要的人 支付流程 前端支付完成,谷歌 ...

  7. Sign in with Apple(object-c) 从开发者后台到服务端验证

    Sign in with Apple 前言 准备工作 开发工作(object-c编写) 基本流程 添加依赖库 创建Apple登录Button 向Apple发起请求 接收Apple的回调 注意: 用户注 ...

  8. JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  9. ios 自己服务器 苹果支付_苹果支付 PHP 服务端处理

    因为上周末连续加班 2 天(产品非要周一上线新版本),因此断更公众号一段时间,今天继续补上. 之前有了微信和支付宝支付后,产品要加上苹果支付,于是有了这篇文章. 一.ios 端流程 itunnes 相 ...

最新文章

  1. 【深度学习】U型的Transfomer网络(Swin-Unet)和Swin-Transformer分类
  2. marin 初学LINUX之路
  3. python读取sqlserver数据库方法_SQLServer数据库之Python读取配置文件,并连接数据库SQL Server...
  4. 教师节,老师们最大的愿望竟然是。。 | 今日最佳
  5. Android studio的Activity详解
  6. php怎么引入外部css文件,js如何引入css外部文件
  7. [转]提高PR值的具体方法
  8. 基于二进制粒子群算法的背包问题求解- 附代码
  9. mysql中文乱码--存入mysql里的中文变成问号的解决办法
  10. 公司网站的访问量突破了每天PV1.5亿
  11. c++缺省值 缺省参数
  12. 用Python实现一个商场管理系统(附源码)
  13. 机器人学笔记之——操作臂运动学:驱动器空间、关节空间和笛卡尔空间
  14. c语言程序小时工资计算,C语言入门之工资计算
  15. Web——HTML常见标签及用法
  16. 2019JDATA店铺购买预测大赛复盘(冠军方案)
  17. Ubuntu下gcc的静态库与动态库的生成与使用
  18. 神经网络分类器的原理图,神经网络分类器是什么
  19. c语言镶嵌循环,讲解C++的do while循环和循环语句的嵌套使用方法
  20. anaconda安装包百度云下载

热门文章

  1. linux搭建xss平台,一个漏洞平台的搭建
  2. 【回答问题】ChatGPT上线了!给我推荐20个比较流行的图神经网络模型
  3. risky to save money in bank
  4. 综合渗透测试实战项目
  5. RV1126与RV1109 AI系统设计概要(一部分)
  6. 白酒风味篇之 清香型白酒(一)
  7. 【枚举】安卓图案解锁题解
  8. 如何更好地使用搜索引擎
  9. 【转载】Concent-Type大全
  10. C语言实现邻接矩阵转换成边集数组,克鲁斯卡尔(Kruskal)算法,并对其优化