From 8f7b2af21beda60d6123f555a0c21d2eadfc777a Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 20 Dec 2019 16:28:41 +0300 Subject: Sign In With Apple --- .../scribejava/apis/AppleClientAuthentication.java | 33 +++++++++ .../apis/AppleClientSecretGenerator.java | 85 ++++++++++++++++++++++ .../com/github/scribejava/apis/AppleSignInApi.java | 45 ++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 src/main/java/com/github/scribejava/apis/AppleClientAuthentication.java create mode 100644 src/main/java/com/github/scribejava/apis/AppleClientSecretGenerator.java create mode 100644 src/main/java/com/github/scribejava/apis/AppleSignInApi.java (limited to 'src/main/java/com/github/scribejava') diff --git a/src/main/java/com/github/scribejava/apis/AppleClientAuthentication.java b/src/main/java/com/github/scribejava/apis/AppleClientAuthentication.java new file mode 100644 index 00000000..6bb919a3 --- /dev/null +++ b/src/main/java/com/github/scribejava/apis/AppleClientAuthentication.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008-2019, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.github.scribejava.apis; + +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication; + +public class AppleClientAuthentication implements ClientAuthentication { + private final AppleClientSecretGenerator generator; + public AppleClientAuthentication(AppleClientSecretGenerator generator) { + this.generator = generator; + } + @Override + public void addClientAuthentication(OAuthRequest request, String apiKey, String apiSecret) { + request.addBodyParameter("client_id", generator.getApplicationId()); + request.addBodyParameter("client_secret", generator.getClientSecret()); + } +} diff --git a/src/main/java/com/github/scribejava/apis/AppleClientSecretGenerator.java b/src/main/java/com/github/scribejava/apis/AppleClientSecretGenerator.java new file mode 100644 index 00000000..3af6bc7a --- /dev/null +++ b/src/main/java/com/github/scribejava/apis/AppleClientSecretGenerator.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008-2019, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.github.scribejava.apis; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.spec.EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.time.*; +import java.util.Base64; +import java.util.Date; + +public class AppleClientSecretGenerator { + private final String subject; + private final String teamId; + private final String keyId; + + private final Key signingKey; + + public AppleClientSecretGenerator(final String subject, final String teamId, final String keyId, final String keyPath) + throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + this.subject = subject; + this.keyId = keyId; + this.teamId = teamId; + + String pemData = FileUtils.readFileToString(new File(keyPath), StandardCharsets.UTF_8); + String p8encodedData = pemData + .replace( + "-----BEGIN PRIVATE KEY-----\n", "") + .replace("\n", "") + .replace("-----END PRIVATE KEY-----", ""); + KeyFactory kf = KeyFactory.getInstance("EC"); + EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(p8encodedData)); + signingKey = kf.generatePrivate(keySpec); + } + + public String getClientSecret() { + Instant now = Instant.now(); + return Jwts.builder() + .setHeaderParam("kid", keyId) + .setIssuer(teamId) + .setAudience("https://appleid.apple.com") + .setIssuedAt(Date.from(now)) + .setSubject(subject) + .setExpiration(Date.from(ZonedDateTime.ofInstant(now, ZoneId.of("UTC")).plusMonths(1).toInstant())) + .signWith(signingKey, SignatureAlgorithm.ES256) + .compact(); + } + + public String getTeamId() { + return teamId; + } + + public String getKeyId() { + return keyId; + } + + public String getApplicationId() { + return subject; + } +} diff --git a/src/main/java/com/github/scribejava/apis/AppleSignInApi.java b/src/main/java/com/github/scribejava/apis/AppleSignInApi.java new file mode 100644 index 00000000..be14ef16 --- /dev/null +++ b/src/main/java/com/github/scribejava/apis/AppleSignInApi.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2019, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication; + +public class AppleSignInApi extends DefaultApi20 { + + private final AppleClientSecretGenerator clientSecretGenerator; + + public AppleSignInApi(AppleClientSecretGenerator clientSecretGenerator) { + this.clientSecretGenerator = clientSecretGenerator; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://appleid.apple.com/auth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://appleid.apple.com/auth/authorize?response_mode=form_post"; + } + + @Override + public ClientAuthentication getClientAuthentication() { + return new AppleClientAuthentication(clientSecretGenerator); + } +} -- cgit v1.2.3