-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b944a3d
commit d771080
Showing
8 changed files
with
171 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/main/java/com/suite/suite_user_service/member/auth/AppleAuth.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.suite.suite_user_service.member.auth; | ||
|
||
import com.suite.suite_user_service.member.auth.appleDto.KeyInfo; | ||
import com.suite.suite_user_service.member.auth.appleDto.Keys; | ||
import com.suite.suite_user_service.member.dto.ReqSignInMemberDto; | ||
import com.suite.suite_user_service.member.handler.CustomException; | ||
import com.suite.suite_user_service.member.handler.StatusCode; | ||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.Jwts; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.parser.JSONParser; | ||
import org.json.simple.parser.ParseException; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
import java.math.BigInteger; | ||
import java.security.KeyFactory; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PublicKey; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.security.spec.RSAPublicKeySpec; | ||
import java.util.Base64; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
@Component | ||
public class AppleAuth { | ||
public static final String APPLE_KEY = "https://appleid.apple.com/auth/keys"; | ||
public static final int HEADER = 0; | ||
public static final int PAYLOAD = 1; | ||
public static final int SIGNATURE = 2; | ||
public static String KID = "kid"; | ||
public static String ALG = "alg"; | ||
public static String ALGORITHM = "RSA"; | ||
|
||
public ReqSignInMemberDto getAppleMemberInfo(String identityToken) { | ||
try { | ||
RestTemplate restTemplate = new RestTemplate(); | ||
Keys keys = restTemplate.getForEntity(APPLE_KEY, Keys.class).getBody(); | ||
|
||
Map<String, String> headerKey = getTokenHeaderInfo(identityToken); | ||
|
||
KeyInfo keyInfo = keys.getKeys().stream().filter( | ||
key -> key.validateKey(headerKey.get(KID), headerKey.get(ALG))).findFirst().orElseThrow( ()-> new CustomException(StatusCode.FORBIDDEN)); | ||
|
||
PublicKey publicKey = getPublicKey(keyInfo); | ||
Claims memberInfo = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(identityToken).getBody(); | ||
JSONObject claims = claimsToJSONObject(memberInfo); | ||
|
||
return ReqSignInMemberDto.builder() | ||
.email(claims.get("email").toString()) | ||
.password(claims.get("sub").toString()) | ||
.isOauth(true).build(); | ||
} catch (ParseException e) { | ||
throw new CustomException(StatusCode.NOT_FOUND); | ||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) { | ||
throw new CustomException(StatusCode.FAILED_SIGNUP); | ||
} | ||
} | ||
|
||
private Map<String, String> getTokenHeaderInfo(String identityToken) throws ParseException { | ||
String[] decodeToken = identityToken.split("\\."); | ||
String headerInfo = new String(Base64.getDecoder().decode(decodeToken[HEADER])); | ||
JSONParser parser = new JSONParser(); | ||
JSONObject keyObject = (JSONObject) parser.parse(headerInfo); | ||
|
||
Map<String, String> map = new HashMap<>(); | ||
map.put(KID, keyObject.get(KID).toString()); | ||
map.put(ALG, keyObject.get(ALG).toString()); | ||
|
||
return map; | ||
} | ||
|
||
private PublicKey getPublicKey(KeyInfo keyInfo) throws NoSuchAlgorithmException, InvalidKeySpecException { | ||
// byte[] nBytes = Base64.getUrlDecoder().decode(keyInfo.getN().substring(1, keyInfo.getN().length() - 1)); | ||
// byte[] eBytes = Base64.getUrlDecoder().decode(keyInfo.getE().substring(1, keyInfo.getE().length() - 1)); | ||
byte[] nBytes = Base64.getUrlDecoder().decode(keyInfo.getN()); | ||
byte[] eBytes = Base64.getUrlDecoder().decode(keyInfo.getE()); | ||
BigInteger n = new BigInteger(1, nBytes); | ||
BigInteger e = new BigInteger(1, eBytes); | ||
|
||
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, e); | ||
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); | ||
return keyFactory.generatePublic(publicKeySpec); | ||
} | ||
|
||
private JSONObject claimsToJSONObject(Claims claims) { | ||
JSONObject jsonObject = new JSONObject(); | ||
jsonObject.putAll(claims); | ||
return jsonObject; | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/suite/suite_user_service/member/auth/appleDto/KeyInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.suite.suite_user_service.member.auth.appleDto; | ||
|
||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class KeyInfo { | ||
private String kty; | ||
private String kid; | ||
private String use; | ||
private String alg; | ||
private String n; | ||
private String e; | ||
|
||
public KeyInfo(String kty, String kid, String use, String alg, String n, String e) { | ||
this.kty = kty; | ||
this.kid = kid; | ||
this.use = use; | ||
this.alg = alg; | ||
this.n = n; | ||
this.e = e; | ||
} | ||
|
||
public boolean validateKey(String kid, String alg) { | ||
if(this.kid.equals(kid) && this.alg.equals(alg)) return true; | ||
return false; | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/suite/suite_user_service/member/auth/appleDto/Keys.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.suite.suite_user_service.member.auth.appleDto; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class Keys { | ||
private List<KeyInfo> keys; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/main/java/com/suite/suite_user_service/member/dto/AppleAuthDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.suite.suite_user_service.member.dto; | ||
|
||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class AppleAuthDto { | ||
private String iss; | ||
private String aud; | ||
private String exp; | ||
private String iat; | ||
private String sub; | ||
private String email; | ||
private String email_verified; | ||
private String auth_time; | ||
private boolean nonce_supported; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters