Spring Security - Apple Sign in with oauth2

Viewed 265

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"))

code to verify apple

0 Answers
Related