본문 바로가기
Language/Java

[Java] 네이버웍스 서비스 계정(JWT) 인증 방법

by 애기 개발자 2025. 4. 28.
반응형

네이버웍스 API를 연동하기 위해 서비스 계정 기반의 JWT 인증 방식을 사용할 수 있습니다.
이 글에서는 서비스 계정으로 JWT를 생성하고, Access Token을 발급받는 과정을 정리합니다.

 

 

서비스 계정으로 인증(JWT) | Developers

 

Developers

 

developers.worksmobile.com

 

1. 준비물

JWT 인증을 위해 다음 4가지 정보를 준비해야 합니다.

  • client_id
  • client_secret
  • service_account
  • private_key

이 값들은 네이버웍스 관리자 포털 또는 개발자 포털에서 발급받을 수 있습니다.

 

인증 흐름

 

서비스 계정 인증은 다음과 같은 순서로 진행됩니다.

  1. JWT 토큰 생성
  2. JWT를 이용해 Access Token 발급
  3. Access Token을 이용해 API 호출

 

 

3. JWT 생성 방법

JWT는 RS256 알고리즘을 사용하여 서명해야 합니다.
아래는 Java 코드로 JWT를 생성하는 방법입니다.

 

private String generateJwt() {
    try {
        // JWT Header
        String header = Base64.getUrlEncoder().withoutPadding()
                .encodeToString("{\"alg\":\"RS256\",\"typ\":\"JWT\"}".getBytes());

        // JWT Payload
        long now = System.currentTimeMillis() / 1000;
        Map<String, Object> payload = new HashMap<>();
        payload.put("iss", CLIENT_ID);
        payload.put("sub", SERVICE_ACCOUNT);
        payload.put("iat", now);
        payload.put("exp", now + 3600); // 1시간 유효

        ObjectMapper mapper = new ObjectMapper();
        String payloadJson = mapper.writeValueAsString(payload);
        String encodedPayload = Base64.getUrlEncoder().withoutPadding()
                .encodeToString(payloadJson.getBytes());

        // Signature
        String dataToSign = header + "." + encodedPayload;
        byte[] signature = sign(dataToSign);
        if(signature == null) {
            log.debug("generateJwt() signature = null");
            return null;
        }
        log.debug("generateJwt() signature = "+signature);

        String encodedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString(signature);

        return header + "." + encodedPayload + "." + encodedSignature;
    } catch (Exception e) {
        e.printStackTrace();
        log.debug("generateJwt() Exception e : "+e);
        return null;
    }
}

private static byte[] sign(String data) {
    try {
        // PEM 형식의 Private Key 파싱
        String privateKeyPem = PRIVATE_KEY.replace("-----BEGIN PRIVATE KEY-----", "")
        .replace("-----END PRIVATE KEY-----", "")
        .replaceAll("\\s+", "");
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyPem);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes());

        return signature.sign();
    } catch (Exception e) {
        e.printStackTrace();
        log.debug("sign() Exception e : "+e);
        return null;
    }
}

 

 

4. Access Token 발급 방법

JWT를 생성한 후, 이를 이용해 Access Token을 발급받습니다.

 

// generateJwt에서 생성한 jwt 값을 파라미터로
private String getAccessToken(String jwt) {
    try {
        // API Endpoint
        URL url = new URL("https://auth.worksmobile.com/oauth2/v2.0/token");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoOutput(true);

        // Request Body
        String body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer"
                + "&assertion=" + jwt
                + "&client_id=" + CLIENT_ID
                + "&client_secret=" + CLIENT_SECRET
                + "&scope=user.read orgunit.read directory.read"; //지정된 범위의 정보만 요청

        try (OutputStream os = conn.getOutputStream()) {
            os.write(body.getBytes());
            os.flush();
        }

        // Response 처리
        if (conn.getResponseCode() == 200) {
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line);
                }

                // JSON에서 access_token 추출
                ObjectMapper mapper = new ObjectMapper();
                Map<String, Object> jsonResponse = mapper.readValue(response.toString(), Map.class);
                log.debug("getAccessToken() jsonResponse = "+jsonResponse);
                return (String) jsonResponse.get("access_token");
            }
        } else {
            log.debug("getAccessToken() HTTP Error: " + conn.getResponseCode());
            return null;
            //throw new IOException("getAccessToken() HTTP Error: " + conn.getResponseCode());
        }
    } catch(Exception e) {
        e.printStackTrace();
        log.debug("getAccessToken() Exception e = "+e);
        return null;
    }
}

 

 

5. 참고사항 및 주의점

  • Private Key는 외부에 절대 노출되지 않도록 주의해야 합니다.
  • Access Token은 일정 시간(기본 1시간) 동안만 유효합니다. 만료되면 재발급이 필요합니다.
  • 실제 API 호출 시 scope를 적절히 지정해야 원하는 데이터에 접근할 수 있습니다.

 

 

위 과정을 통해 네이버웍스 서비스 계정을 이용한 JWT 인증 및 Access Token 발급이 완료되었습니다.

Access Token을 발급받은 이후에는
네이버웍스의 다양한 API 엔드포인트를 호출하여 사용자 정보, 조직도 정보 등을 조회할 수 있습니다.

 

작성일: 2025년 4월 기준
※ 네이버웍스 API는 향후 업데이트에 따라 내용이 변경될 수 있습니다.

 

반응형

댓글