Ошибка: неверный клиент - войдите в Apple с помощью Spring Boot - PullRequest
0 голосов
/ 14 апреля 2020

Я получаю ошибку 400 : [{"error":"invalid_client"}] при попытке обменять код авторизации на токен refre sh. Я перепробовал все и перепроверил много раз. Я использую эту библиотеку для генерации секрета клиента. Ниже я использовал образец ключа для демонстрации проблемы. Что может быть не так?

Генератор Apple Client Secret

public class AppleClientSecretGenerator {

    private String team_id;
    private String sub;
    private String key_id;
    private long expiration_time;
    private String secret_key;
    private String aud;


    public AppleClientSecretGenerator() {
        super();
        this.team_id = "***********";
        this.sub = "com.example.app";
        this.key_id = "**********";
        this.expiration_time = 200000;
        this.secret_key = "MIGTAFKMN23SFF2SFGSM49AgEGCCqGSM49AwEHBHdfDSFFDe09hGVEu5sesMNNF" +
                "pet8GJDZIL0inL4oxgIJNF0i3Q8MYKOgsdCgYIKoZIzj0DAQehRANCAAQhAVyKVrFGWEw+" +
                "gkWyeQNxopjG30iF56DXM0QfqwbffKmsdPkjfe3FKDDFyDYmk+XZM4qj6aIZKLy" +
                "KLM4Nd23";
        this.aud = "https://appleid.apple.com";
    }

    public String generate() {
        String jws = "";
        try {
            byte[] keyBytes = Base64.getDecoder().decode(secret_key);
            //byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.ES256;
            long nowSeconds = System.currentTimeMillis();
            Date now = new Date(nowSeconds);
            long expMillis = nowSeconds + expiration_time;
            Date exp = new Date(expMillis);

            jws = Jwts.builder()
                    .setHeaderParam("kid", key_id)
                    .setIssuedAt(now)
                    .setSubject(sub)
                    .setIssuer(team_id)
                    .setAudience(aud)
                    .setExpiration(exp)
                    .signWith(key, signatureAlgorithm)
                    .compact();
        } catch (JwtException e) {
            //don't trust the JWT!
            System.out.println("Error: " + e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
        System.out.println("Client Secret: " + jws);
        return jws;

    }
}

Запрос авторизации

public class AuthorizationRequest {

    private String client_id;
    private String client_secret;
    private String code;
    private String grant_type;
    private String redirect_uri;


    public AuthorizationRequest(String client_secret, String code) {
        super();
        this.client_id = "com.maxtrauboth.BopdropSwiftUI";
        this.client_secret = client_secret;
        this.code = code;
        this.grant_type = "authorization_code";
        this.redirect_uri = "http://mylocaladdr.test/";
    }

// Getters and Setters here

Подтвердить пользователя

@PostMapping("verify")
public UserCredentials verify(@RequestBody UserCredentials credentials) {

        Jwk jwk;
        Algorithm algorithm;

        // Validate identity token
        DecodedJWT jwt = JWT.decode(credentials.getToken());
        JwkProvider provider = new UrlJwkProvider("https://appleid.apple.com/auth/keys");

        try {
            jwk = provider.get(jwt.getKeyId());
            algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
            algorithm.verify(jwt);

            // Check expiration
            if (jwt.getExpiresAt().before(Calendar.getInstance().getTime())) {
              throw new RuntimeException("Expired token!");
            }

            // Create client_secret
            AppleClientSecretGenerator generator = new AppleClientSecretGenerator();
            String client_secret = generator.generate();

            // Refreshing the token by sending the authorization code
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED));
            headers.set("User-Agent", "Mozilla/5.0 Firefox/26.0");

            System.out.println("Authorization Code: " + credentials.getAuthorization_code());

            AuthorizationRequest request = new AuthorizationRequest(client_secret, credentials.getAuthorization_code());

            HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

            RestTemplate restTemplate = new RestTemplate();

            // send POST request
            TokenResponse response = restTemplate.postForObject("https://appleid.apple.com/auth/token", entity, TokenResponse.class);

            // do some database work here

        } catch (JwkException e) {
            // error
        } catch (IllegalArgumentException e) {
            // error
        }

        // sending the token back to the user 
        return credentials;
}

Сгенерированный секрет клиента

{
  "kid": "*********",
  "alg": "ES256"
}
{
  "iss": "*********",
  "iat": 1587930164,
  "exp": 1587930364,
  "aud": "https://appleid.apple.com",
  "sub": "com.example.app"
}

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Я не нашел причину проблемы. Однако, я решил проблему, выполнив точные шаги, упомянутые здесь .

0 голосов
/ 17 апреля 2020

Время выдачи и истечения должно быть в секундах, а не в миллисекундах.

...