has anyone done Apple login for oauth2 in Spring Security?
I have written all oauth2 logic for Facebook and Google and here the whole mechanism works fine, but I have a problem with Apple. I have methods to create client-secret based on p8 key, but I don't know at what point to plug it in, since it uses /api/oauth2/authorize/apple with oauth2.
Below I submit a method to make a request to Apple, but when to call it on the oauth2 side? Where in react native do I still get this code to be sent from iOS?
Could I get some help as I've been sitting for a few days now and don't really know how to bite this Apple.
Action to verify apple:
@Component
@RequiredArgsConstructor
public class AppleRestTemplate {
private final JwtTokenUtil jwtTokenUtil;
@Value("${spring.security.oauth2.client.provider.apple.tokenUri}")
private String tokenUrl;
@Value("${spring.security.oauth2.client.provider.apple.jwkSetUri}")
private String jwkSetUrl;
@Value("${spring.security.oauth2.client.registration.apple.client-id}")
private String clientId;
@Value("${spring.security.oauth2.client.registration.apple.redirectUri}")
private String redirectUri;
public String getAuthTokenFromApple(String code) throws Exception {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/x-www-form-urlencoded");
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("client_id", clientId);
parameters.add("client_secret", jwtTokenUtil.generateJWT());
parameters.add("code", code);
parameters.add("grant_type", "authorization_code");
parameters.add("redirect_uri", redirectUri);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(parameters, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(tokenUrl, entity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
AppleIdTokenResponse appleIdTokenResponse = new ObjectMapper().readValue(responseEntity.getBody(), AppleIdTokenResponse.class);
System.out.println(appleIdTokenResponse.getId_token());
return getUserInfo(appleIdTokenResponse);
}
return "Failed to Auth Token";
}
private String getUserInfo(AppleIdTokenResponse appleIdTokenResponse) throws InvalidKeySpecException, NoSuchAlgorithmException {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Key> responseEntity = restTemplate.getForEntity(jwkSetUrl, Key.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
System.out.println(Objects.requireNonNull(responseEntity.getBody()).getKeys().size());
return jwtTokenUtil.createPublicKeyApple(appleIdTokenResponse, responseEntity.getBody().getKeys());
}
return "Email id Not Found";
}
}
Client Secret - I do with this code:
public String generateJWT() throws Exception {
PrivateKey pKey = generatePrivateKey();
return Jwts.builder()
.setHeaderParam(JwsHeader.KEY_ID, appleKeyId)
.setIssuer(appleTeamId)
.setAudience("https://appleid.apple.com")
.setSubject(clientId)
.setExpiration(new Date(System.currentTimeMillis() + (1000 * 60 * 5)))
.setIssuedAt(new Date(System.currentTimeMillis()))
.signWith(SignatureAlgorithm.ES256, pKey)
.compact();
}
private PrivateKey generatePrivateKey() throws Exception {
File file = ResourceUtils.getFile("classpath:apple/AuthKey_KGVBF46FGM.p8");
final PEMParser pemParser = new PEMParser(new FileReader(file));
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
final PrivateKeyInfo object = (PrivateKeyInfo) pemParser.readObject();
final PrivateKey pKey = converter.getPrivateKey(object);
pemParser.close();
return pKey;
}
And this is my config in Spring Security:
.oauth2Login()
.loginPage("/")
.authorizationEndpoint()
.baseUri("/api/oauth2/authorize")
.authorizationRequestRepository(cookieAuthorizationRequestRepository())
.and()
.redirectionEndpoint()
.baseUri("/api/oauth2/callback/*")
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler((request, response, exception) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"))