2015-06-11 16 views
21

मैं OAuth2 जेडब्ल्यूटी टोकन सत्यापन अपवाद पिछले एक घंटे का सामना करना पड़ रहा है (ताकि कोई भी अपने आवेदन का उपयोग कर सकते):गूगल OAuth2 जेडब्ल्यूटी टोकन सत्यापन अपवाद

java.security.SignatureException: हस्ताक्षर लंबाई सही नहीं: 256 मिला लेकिन उम्मीद कर रहा था 128. मैं google-http-client 1.20.0 और Java 1.7.0 का उपयोग कर रहा हूं। वही विन्यास अभी तक काम करता है - कोई विचार?

Stacktrace 

java.security.SignatureException: Signature length not correct: got 256 but was expecting 128 
    at sun.security.rsa.RSASignature.engineVerify(Unknown Source) ~[na:1.7.0_45] 
    at java.security.Signature$Delegate.engineVerify(Unknown Source) ~[na:1.7.0_45] 
    at java.security.Signature.verify(Unknown Source) ~[na:1.7.0_45] 
    at com.google.api.client.util.SecurityUtils.verify(SecurityUtils.java:164) ~[google-http-client-1.20.0.jar:1.20.0] 
+0

जावा 1.8.0_45 का उपयोग करने के साथ ही वही समस्या। – brunnsbe

+0

मैं Google खाता प्रबंधक खाते से एक्सेस टोकन का उपयोग करते समय इसे Google ऐप इंजन पर प्राप्त कर रहा हूं। (बस एक घंटे पहले उन्हें प्राप्त करना शुरू किया) –

+1

@ user3686724 GoogleIdTokenVerifier के लिए आपने जो ऑडियंस सेट किया है वह क्या है? क्या आप क्लाइंट आईडी या टोकन आईडी का उपयोग करते हैं? (हम पिछले 60 मिनट के लिए एक ही समस्या का सामना कर रहे हैं) – orrsella

उत्तर

7

एक ही समस्या यहाँ, मैं अपने प्रोजेक्ट के लिए GoogleIdTokenVerifier के स्रोत कोड जोड़ा गया है और तरीके को बदल दिया:

public boolean verify(GoogleIdToken googleIdToken) throws GeneralSecurityException, IOException { 
    // check the payload 
    if (!super.verify(googleIdToken)) { 
     return false; 
    } 
    // verify signature 
    for (PublicKey publicKey : publicKeys.getPublicKeys()) { 
     try { 
     if (googleIdToken.verifySignature(publicKey)) { 
      return true; 
      } 
    } catch (Exception e) { 
     System.err.println("Verify Token:" + e); 
    } 
    } 
    return false; 
    } 

सिर्फ अपवाद संभाल, दूसरा प्रमाण पत्र ठीक काम करता है।

संपादित करें:

संपादित करें 2:: मैं, यह नीचे दिए गए कोड का उपयोग कर काम नहीं कर सकते हैं मैं ऊपर बदसूरत हैक करने के लिए छड़ी के रूप में Erik-z सुझाव अगर आप इसे और अधिक स्वच्छ बनाना चाहते आप उपवर्ग कर सकते हैं।

package com.my.project.package; 

import java.io.IOException; 
import java.security.GeneralSecurityException; 
import java.security.PublicKey; 

import com.google.api.client.auth.openidconnect.IdTokenVerifier; 
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; 
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.json.JsonFactory; 

// Remember to remove this class later by making it deprecated 
@Deprecated 
public class GoogleIdTokenVerifier2 extends GoogleIdTokenVerifier { 

    // Add constructors as needed 
    public GoogleIdTokenVerifier2(HttpTransport transport, JsonFactory jsonFactory) { 
     super(transport, jsonFactory); 
    } 

    @Override 
    public boolean verify(GoogleIdToken googleIdToken) throws GeneralSecurityException, IOException { 
     // check the payload 
     if (!((IdTokenVerifier)this).verify(googleIdToken)) { 
      return false; 
     } 
     // verify signature 
     for (PublicKey publicKey : getPublicKeysManager().getPublicKeys()) { 
      try { 
       if (googleIdToken.verifySignature(publicKey)) { 
        return true; 
       } 
      } catch (Exception e) { 
       System.err.println("Verify Token:" + e); 
      } 
     } 
     return false; 
    } 
} 
5

यह अंतिम समाधान है, लेकिन एक अस्थायी काम के आसपास जो निश्चित रूप से काम करता है tokenId को सत्यापनकर्ता के दर्शकों को बदलने के लिए है मत सोचो।

https://www.googleapis.com/oauth2/v1/certs

आप उनमें से आदेश को समायोजित कर सकते हैं:

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory).setAudience(Arrays.asList(clientId)).build(); 

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) 
        .setAudience(Arrays.asList(tokenResponse.getIdToken())).build(); 
+0

धन्यवाद, इटाई! यह कामकाज भी मेरे कोड पर काम कर रहा है। मेरी कंपनी के लिए एक गंभीर उत्पादन मुद्दे के लिए अच्छा रोकथाम। – kennbrodhagen

+0

सुनकर खुशी हुई :-) मुझे लगता है, लेकिन यकीन नहीं है कि प्रभावी रूप से यह केवल सत्यापन बंद कर देता है। यह संभव है कि Google ने प्रमाण पत्र जांच को कठोर कर दिया है और यही कारण है कि अचानक वृद्धि हुई। – Ittai

2

मूल कारण गूगल तरफ है करने के लिए, JSON में प्रमाणपत्र बुरा क्रम में है , इस तरह:

http://test.gacivs.info/frontend/certs.json

के बाद, आप अपने कस्टम URL (या निर्दिष्ट कर सकते हैं विधि GooglePublicKeysManager.setPublicCertsEncodedUrl (...) के साथ JSON का मेरा :) का उपयोग कर:

final GoogleIdToken idToken = GoogleIdToken.parse(JSON_FACTORY, token); 
final GooglePublicKeysManager manager = new GooglePublicKeysManager.Builder(HTTP_TRANSPORT, JSON_FACTORY).setPublicCertsEncodedUrl(CUSTOM_CERTS_URL).build(); 
final GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(manager).setAudience(Arrays.asList(CLIENT_ID)).build(); 
verifier.verify(idToken); 

... और यह काम करता है।

मुझे आशा है कि, गूगल जल्द ही इस मुद्दे को ठीक ... :)

+0

ओह, यह तय है। :) –

0

यह मेरा जवाब here से नकल है, लेकिन Google मेघ Endpoint (इस सवाल का मिलान) का उपयोग नहीं कर उन लोगों के लिए अधिक प्रासंगिक। समस्या इस वजह से होती है:

  • आरएसए के आकार के आधार पर परिवर्तनीय लंबाई हस्ताक्षर हैं।
  • गूगल कुंजी युग्म यह हस्ताक्षर करने के लिए उपयोग करता है अद्यतन, और अब कुंजी युग्म से एक अन्य
  • java.security.Signature.verify(byte[] signature) से एक अलग लंबाई हस्ताक्षर उत्पन्न करता है, तो गलत लंबाई के एक हस्ताक्षर पारित हो जाता है (बजाय झूठे लौटने का एक अपवाद फेंकता है जो सामान्य रूप से किया जाता है जब एक हस्ताक्षर कुंजी से मेल नहीं खाता)

सरल समाधान की पुष्टि कॉल (try...catch) लपेट, और झूठे वापसी अगर आप http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html पर उदाहरण कोड को देखते हुए एक अपवाद

प्राप्त करने के लिए है ऐसा लगता है कि आप च कर सकते हैं Ange इस लाइन:

GoogleIdToken token = GoogleIdToken.parse(mJFactory, tokenString); 

JsonWebSignature jws = JsonWebSignature.parser(mJFactory).setPayloadClass(Payload.class).parse(tokenString); 
GoogleIdToken token = new GoogleIdToken(jws.getHeader(), (Payload) jws.getPayload(), jws.getSignatureBytes(), jws.getSignedContentBytes()) { 
    public boolean verify(GoogleIdTokenVerifier verifier) 
    throws GeneralSecurityException, IOException { 
     try { 
      return verifier.verify(this); 
     } catch (java.security.SignatureException e) { 
      return false; 
     } 
    } 
}; 

को मैं दुर्भाग्य से इस परीक्षण करने के लिए एक सटीक सेटअप नहीं है, मुझे पता है अगर यह आपके लिए काम करता है।

0

ऐसा लगता है कि पुस्तकालय बुरी तरह व्यवहार कर रहे हैं। ऑफ़लाइन टोकन सत्यापन के विकल्प के रूप में, आप टोकन को सत्यापित करने के लिए Google के OAuth2 एंडपॉइंट्स का उपयोग कर सकते हैं। एपीआई एक्सप्लोरर can be seen here से एक मूल उदाहरण।

आप एक कर्ल आदेश curl https://www.googleapis.com/oauth2/v2/tokeninfo?id_token=[id_token] साथ टोकन जांच कर सकते हैं, उदाहरण के लिए:

curl https://www.googleapis.com/oauth2/v2/tokeninfo?id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjRlYjczOTg0MzBkNTNjZjZjNGZkMGU5YmM4NzkzZWViZWNkMWY1NWUifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTA3Mzc3MTkxNjgxODAyNjY5ODY2IiwiYXpwIjoiMTE2MjY4ODY3NTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdF9oYXNoIjoieGJSVGJOdFJYRnJzcUJHTkRtRTR6USIsImF1ZCI6IjExNjI2ODg2NzUyLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiY19oYXNoIjoiU3JFa25WczRUejhQSWJicExnNXF2QSIsImlhdCI6MTQzNDA0MTY5OSwiZXhwIjoxNDM0MDQ1Mjk5fQ.vqQXCTFfbDqpTYnfFrDD7m68oEuGqd8NWa4s9wstOrrcyuVKUsqFXM_2bH-un_4C8UBvqtQEyzU_-53DxgvhCHQ7S0W-wtQ9YMoJcy7iL1wDjcy1p7aFVoeGCoqxWv1vzlWTUDu_FnD9oIBSAawyDexvRwwGxN8O1D8nzyj__1DQ_ivxIMF-j1W89mc7adK4p5B8ioZA_PI-AGawX2Nm8t58yBMIYrTk0XExr9Pf4eHHRGbrQxcd0ERGHbRMYuG6k-MzdnVNHIScgZ3Cixx9v15PbQ5hXExNvleifG_Wk3Thnz0j6Uacr4fbi-mO93-h8c0r3BSvQ270_JqlpL5q5Q 
0

आप नहीं करना चाहते हैं (या नहीं कर सकते हैं) गूगल पुस्तकालय के स्रोत बदलते हैं, तो आप सिर्फ विस्तार कर सकते हैं GoogleIdTokenVerifier। (आपको किसी अन्य विधि को डुप्लिकेट करना होगा जो कुछ निजी चरों तक पहुंचता है - सौभाग्य से वे सभी सदस्यों के माध्यम से सुलभ हैं)। यह मेरे लिए काम करता है:

GoogleIdTokenVerifier myVerifier = new GoogleIdTokenVerifier(httpTransport, jsonFactory) { 

    public boolean superVerify(IdToken idToken) { 
       return (getIssuer()== null || idToken.verifyIssuer(getIssuer())) 
        && (getAudience() == null || idToken.verifyAudience(getAudience())) 
        && idToken.verifyTime(getClock().currentTimeMillis(), getAcceptableTimeSkewSeconds()); 
    } 


    @Override 
    public boolean verify(GoogleIdToken googleIdToken) throws GeneralSecurityException, IOException { 
     // check the payload 
     if (!superVerify(googleIdToken)) { 
      log.info("superVerify returned false"); 
     return false; 
     } 
     // verify signature 
     for (PublicKey publicKey : getPublicKeysManager().getPublicKeys()) { 
       try { 
         if (googleIdToken.verifySignature(publicKey)) { 
           log.info("verifySignature: success!"); 
           return true; 
         } 
       } catch (Exception e) { 
         log.info("error verifying!", e); 
       } 
     } 
     return false; 
    } 

}; 
संबंधित मुद्दे