invalid_client ошибка вызова входа с помощью Apple Rest API - PullRequest
0 голосов
/ 30 марта 2020

Мы начали внедрять вход с помощью Apple в наше мобильное приложение, но не можем успешно вызвать конечную точку токена (https://appleid.apple.com/auth/token). Мы получаем ответ 400 с телом [{"error": "invalid_client"}]. Я прочитал и перечитал детали о том, как генерировать секрет клиента. Мы используем java бэкэнд и, в частности, библиотеку nimbus для создания подписанного JWT.

final JWSHeader clientSecretHeader = 
  new JWSHeader.Builder(JWSAlgorithm.ES256)  
    .keyID("7N5XJ*****")  
    .build();  
final Date issuedAtTime = Date.from(Instant.now());  
final Date expirationTime = Date.from(Instant.now().plusSeconds(3600));  
final JWTClaimsSet clientSecretClaims =   
  new JWTClaimsSet.Builder()  
   .issuer("HL46P*****")  
   .issueTime(issuedAtTime)  
   .expirationTime(expirationTime)  
   .audience("https://appleid.apple.com")  
   .subject("com.company.app")  
   .build();  
final byte[] keyBytes = ...private key loaded from p8 file...;  
final KeyFactory keyFactory = KeyFactory.getInstance("EC");
final ECPrivateKey privateKey =
  (ECPrivateKey)keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
final JWSSigner jwtSigner = new ECDSASigner(signingKey);  
final SignedJWT clientSecretJwt = new SignedJWT(clientSecretHeader, clientSecretClaims);  
clientSecretJwt.sign(jwtSigner);

final MultiValueMap<string, string=""> map= new LinkedMultiValueMap<>();  
map.add("grant_type", "authorization_code");  
map.add("client_id", "HL46P*****");  
map.add("client_secret", clientSecretJwt.serialize());  
map.add("code", "code receiged from app...");

/* if User-Agent is not set, request fails with 400 invalid_client */
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set(HttpHeaders.USER_AGENT, "My App");

final HttpEntity<multivaluemap<string, string="">> request = new HttpEntity<>(map, headers);  
final RestTemplate restTemplate = new RestTemplateBuilder().build();  
final ResponseEntity response = response = restTemplate.postForEntity(  
  "https://appleid.apple.com/auth/token",  
  request,  
  GetTokenResponse.class  
 );  

Полученный JWT выглядит следующим образом:

Заголовок

{  
  "kid": "7N5XJ*****",  
  "alg": "ES256"  
}

Заявления

{  
  "aud": "https://appleid.apple.com",  
  "sub": "com.company.app",  
  "iss": "HL46P.....",  
  "exp": 1585583898,  
  "iat": 1585580298  
}

В итоге мы определили, что если заголовок User-Agent не задан, API Apple не будет работать с кодом ответа 400 и invalid_client в качестве ошибки. Эта ошибка полностью вводит в заблуждение, но установка заголовка User-Agent разрешает ее.

...