2013-01-07 40 views
8

के लिए Google एपीआई [google-oauth-java-client-1.12.0-beta] का उपयोग करके टोकन प्राप्त करने में असमर्थ मैं Google API (संस्करण google-oauth-java-client-1.12.0-beta) का उपयोग कर रहा हूं ओएथ 2 एक्सेस टोकन प्राप्त करने के लिए लेकिन "अवैध_ग्रेंट" वापस मिला। रेफरी: https://developers.google.com/accounts/docs/OAuth2ServiceAccountसेवा खाता प्रवाह

यहाँ कोड है:

import com.google.api.client.auth.jsontoken.JsonWebSignature; 
import com.google.api.client.auth.jsontoken.JsonWebToken; 
import com.google.api.client.auth.jsontoken.RsaSHA256Signer; 
import com.google.api.client.auth.oauth2.TokenRequest; 
import com.google.api.client.auth.oauth2.TokenResponse; 
import com.google.api.client.http.GenericUrl; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.http.javanet.NetHttpTransport; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.client.util.Clock; 

import java.io.FileInputStream; 
import java.io.IOException; 

import java.security.GeneralSecurityException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.CertificateException; 


public class TestClient 
{ 
    private static PrivateKey getPrivateKey(String keyFile, String alias, String password) 
    throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException 
    { 
    KeyStore keystore = KeyStore.getInstance("PKCS12"); 
    keystore.load(new FileInputStream(keyFile), password.toCharArray()); 
    PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, password.toCharArray()); 

    return privateKey; 
    } 

    public static void main(String[] args) 
    throws GeneralSecurityException, IOException 
    { 
    String password = "notasecret"; 
    String alias = "privatekey"; 
    String keyFile = "<private key file>.p12"; 
    String serviceAccountScopes = "https://www.googleapis.com/auth/urlshortener"; 
    String serviceAccountUser = "[email protected]"; 
    String serviceAccountId = "<a/c id>.apps.googleusercontent.com"; 
    JsonWebSignature.Header header = new JsonWebSignature.Header(); 
    header.setAlgorithm("RS256"); 
    header.setType("JWT"); 

    JsonWebToken.Payload payload = new JsonWebToken.Payload(Clock.SYSTEM); 
    long currentTime = Clock.SYSTEM.currentTimeMillis(); 
    payload.setIssuer(serviceAccountId) 
     .setAudience("https://accounts.google.com/o/oauth2/token") 
     .setIssuedAtTimeSeconds(currentTime/1000) 
     .setExpirationTimeSeconds(currentTime/1000 + 3600) 
     .setPrincipal(serviceAccountUser); 
    payload.put("scope", serviceAccountScopes); 
    System.out.println(payload.toPrettyString()); 

    PrivateKey serviceAccountPrivateKey = getPrivateKey(keyFile, alias, password); 
    String assertion = RsaSHA256Signer.sign(serviceAccountPrivateKey, getJsonFactory(), header, payload);  
    TokenRequest request = new TokenRequest(getTransport(), getJsonFactory(), new GenericUrl(getTokenServerEncodedUrl()), "assertion");  

    request.put("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");  
    request.put("assertion", assertion);  
    TokenResponse resp = request.execute();  
    System.out.println("token : " + resp.getAccessToken()); 
    } 

    private static String getTokenServerEncodedUrl() 
    { 
    return "https://accounts.google.com/o/oauth2/token"; 
    } 

    private static JsonFactory getJsonFactory() 
    { 
    return new JacksonFactory(); 
    } 

    private static HttpTransport getTransport() 
    { 
    return new NetHttpTransport(); 
    } 
} 

परिणाम:

Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request 
{ 
    "error" : "invalid_grant" 
} 
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:103) 
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303) 
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323) 

समस्या यहाँ क्या है? किसी भी संकेत की सराहना की जाएगी।

उत्तर

7

Google सेवाओं और Google एपीआई क्लाइंट लाइब्रेरी पर सेवा खातों का उपयोग करते समय आपको हस्ताक्षर बनाने और जेडब्ल्यूटी टोकन का निर्माण करने की आवश्यकता नहीं है क्योंकि रीड-टू-यूज यूटिलिटी क्लासेस केवल सेवा खाते प्रमाणीकरण के माध्यम से काम करते हैं ओथ 2.0।

हालांकि यह Google ड्राइव प्रलेखन को छोड़कर बहुत अच्छी तरह से प्रलेखित नहीं है जिसमें एकाधिक प्रोग्रामिंग भाषाओं में विस्तृत स्पष्टीकरण और कोड नमूने शामिल हैं। आप पढ़ना चाहिए: अपने कोड के साथ https://developers.google.com/drive/service-accounts#google_apis_console_project_service_accounts

कुछ मुद्दों:

  • सेवा खाते की आईडी रूप में होना चाहिए: <some-id>@developer.gserviceaccount.com (हाँ ग्राहक आईडी के बजाय ईमेल, मैं जानता हूँ कि यह अजीब है)
  • Google Apps domain Wide delegation करते समय आप केवल principal सेट करते हैं लेकिन आप जीमेल खातों पर ऐसा नहीं कर सकते हैं, केवल Google Apps खातों पर जिनके डोमेन को आपको व्यवस्थापक द्वारा एक्सेस प्रदान किया गया है, इसलिए आपके मामले में: इसे सेट न करें ।

नीचे जावा में OAuth 2.0 w/सेवा खातों के लिए कोड नमूना है।

नोट: आपको the URL Shortener library डाउनलोड करने की भी आवश्यकता होगी।

/** Email of the Service Account */ 
private static final String SERVICE_ACCOUNT_EMAIL = "<some-id>@developer.gserviceaccount.com"; 

/** Path to the Service Account's Private Key file */ 
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "/path/to/<public_key_fingerprint>-privatekey.p12"; 

/** 
* Build and returns a URL Shortner service object authorized with the service accounts. 
* 
* @return URL Shortner service object that is ready to make requests. 
*/ 
public static Drive getDriveService() throws GeneralSecurityException, IOException, URISyntaxException { 
    HttpTransport httpTransport = new NetHttpTransport(); 
    JacksonFactory jsonFactory = new JacksonFactory(); 
    GoogleCredential credential = new GoogleCredential.Builder() 
     .setTransport(httpTransport) 
     .setJsonFactory(jsonFactory) 
     .setServiceAccountId(SERVICE_ACCOUNT_EMAIL) 
     .setServiceAccountScopes(UrlshortenerScopes.URLSHORTENER) 
     .setServiceAccountPrivateKeyFromP12File(
      new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH)) 
     .build(); 
    Urlshortener service = new Urlshortener.Builder(httpTransport, jsonFactory, null) 
     .setHttpRequestInitializer(credential).build(); 
    return service; 
} 
+1

ऐडसेंस के साथ काम करते समय भी यह "अवैध_ग्रांत" अपवाद प्राप्त हो रहा है। क्लाइंट आईडी मान्य है, स्कोप AdSenseScopes.ADSENSE है। ऐडसेंस प्रबंधन एपीआई सक्रिय है। कोई संकेत नहीं है कि इसे कैसे ठीक किया जाए – user12384512

+0

मेरे लिए बहुत उपयोगी है, यहां तक ​​कि मैं नोडजेएस रैपर के साथ भी काम करता हूं। मेरा मुद्दा यह था कि मैंने आवेदन ईमेल पते के बजाय अपना खाता ईमेल इस्तेमाल किया था। धन्यवाद! –

+0

क्या एक शानदार जवाब है! मुझे Google शीट्स जावा एपीआई के साथ जेडब्ल्यूटी त्रुटियां मिल रही थीं। कोई भाग्य समाधान नहीं ढूंढ रहा है। यह एक सेवा खाते के माध्यम से Google एपीआई सेवाओं के लिए प्रमाण पत्र प्राप्त करने के लिए एक काम कर रहे जावा कोड उदाहरण को खोजने के लिए लगभग असंभव था (इस धागे को छोड़कर)। जब मैंने आपके उत्तर को प्रतिबिंबित करने के लिए अपने प्रमाण-पत्रों को बदल दिया, तो अब मैं सक्षम हूं Google शीट्स एपीआई के माध्यम से एक निजी को सफलतापूर्वक अनुरोध करें। साथ ही, चादरों के साथ काम करते समय, सुनिश्चित करें कि आप अपने सेवा खाते के ईमेल पते (अपनी डाउनलोड की गई जेसन कुंजी/पहचान फ़ाइल में) – ganta