2015-10-10 4 views
15

Ich habe einen Anwendungsfall, um OAuth1-Anfrage zu authentifizieren, die mit RSA Private Key signiert und am Server Ende mit RSA Public Key verifiziert wird.OAuth1a signierte Anfrage mit Twitter joauth mit RSA-SHA1 bestätigen?

Ich habe diese Bibliothek von Twitter gefunden, mit der wir die von Oauth signierten Anfragen authentifizieren/verifizieren können. https://github.com/twitter/joauth

Ich möchte diese Bibliothek für die Überprüfung der Anfrage von Jersey oder Spring MVC Aktionsmethode nutzen. Die Anfrage vom Client wäre mit einem privaten Schlüssel signiert worden. An meinem Ende würde ich den öffentlichen Schlüssel des Clients verwenden, um die Anfrage zu überprüfen. was bedeutet RSA-SHA1 Algo.

Twitter joauth scheint nützlich zu sein, aber ich den Code fehle, die HttpServletRequest zu OAuthRequest

Die Bibliothek readme Datei schlägt vor, dies als Einrichtung verwandeln würde, aber ich kann nicht einen Code finden, die javax.servlet.http.HttpServletRequest tut ->com.twitter.joauth.OAuthRequest Transformation.

Die Anforderungsverifizierung erfolgt in Verify-Methode, die folgende Signatur hat.

public VerifierResult verify(UnpackedRequest.OAuth1Request request, String tokenSecret, String consumerSecret); 

Zweitens weiß ich mag auch, welche der am besten geeignete Weg ist, öffentlichen RSA-Schlüssel mit twitter joauth verwenden/lesen, wenn Methode String-Parameter nimmt überprüfen?

+0

Welche Version von JOAuth verwenden Sie? – Val

Antwort

1

Ich habe noch nie eine Bibliothek verwendet, um Benutzer über Twitter zu authentifizieren. Aber ich habe gerade im UnpackedRequest.OAuth1Request nachgesehen. Sie können eine Instanz dieser Klasse erstellen, indem Sie alle Parameter füllen. Ich habe Twitter OAuth Header Creator geschrieben, so dass Sie es einfach verwenden können, um diese Parameter zu füllen oder POST-Anfragen direkt ohne eine Bibliothek zu senden.

Hier werden alle Klassen, was Sie brauchen:

Signature - ein OAuth Unterschrift zu erzeugen.

public class Signature { 
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1"; 
    public static String calculateRFC2104HMAC(String data, String key) 
      throws java.security.SignatureException 
    { 
     String result; 
     try { 
      SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM); 
      Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM); 
      mac.init(signingKey); 
      byte[] rawHmac = mac.doFinal(data.getBytes()); 
      result = new String(Base64.encodeBase64(rawHmac)); 
     } catch (Exception e) { 
      throw new SignatureException("Failed to generate HMAC : " + e.getMessage()); 
     } 
     return result; 
    } 
} 

NvpComparator - Parameter, die Sie in der Kopfzeile müssen sortieren.

public class NvpComparator implements Comparator<NameValuePair> { 
    @Override 
    public int compare(NameValuePair arg0, NameValuePair arg1) { 
     String name0 = arg0.getName(); 
     String name1 = arg1.getName(); 
     return name0.compareTo(name1); 
    } 
} 

OAuth - für URL kodieren.

class OAuth{ 
... 
    public static String percentEncode(String s) { 
      return URLEncoder.encode(s, "UTF-8") 
        .replace("+", "%20").replace("*", "%2A") 
        .replace("%7E", "~"); 
    } 
... 
} 

HeaderCreator - alle benötigten Parameter zu erstellen und ein OAuth-Header param erzeugen.

public class HeaderCreator { 
    private String authorization = "OAuth "; 
    private String oAuthSignature; 
    private String oAuthNonce; 
    private String oAuthTimestamp; 
    private String oAuthConsumerSecret; 
    private String oAuthTokenSecret; 

    public String getAuthorization() { 
     return authorization; 
    } 

    public String getoAuthSignature() { 
     return oAuthSignature; 
    } 

    public String getoAuthNonce() { 
     return oAuthNonce; 
    } 

    public String getoAuthTimestamp() { 
     return oAuthTimestamp; 
    } 

    public HeaderCreator(){} 

    public HeaderCreator(String oAuthConsumerSecret){ 
     this.oAuthConsumerSecret = oAuthConsumerSecret; 
    } 

    public HeaderCreator(String oAuthConsumerSecret, String oAuthTokenSecret){ 
     this(oAuthConsumerSecret); 
     this.oAuthTokenSecret = oAuthTokenSecret; 
    } 

    public String getTwitterServerTime() throws IOException, ParseException { 
     HttpsURLConnection con = (HttpsURLConnection) 
       new URL("https://api.twitter.com/oauth/request_token").openConnection(); 
     con.setRequestMethod("HEAD"); 
     con.getResponseCode(); 
     String twitterDate= con.getHeaderField("Date"); 
     DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH); 
     Date date = formatter.parse(twitterDate); 
     return String.valueOf(date.getTime()/1000L); 
    } 

    public String generatedSignature(String url, String method, List<NameValuePair> allParams, 
            boolean withToken) throws SignatureException { 
     oAuthNonce = String.valueOf(System.currentTimeMillis()); 
     allParams.add(new BasicNameValuePair("oauth_nonce", oAuthNonce)); 
     try { 
      oAuthTimestamp = getTwitterServerTime(); 
      allParams.add(new BasicNameValuePair("oauth_timestamp", oAuthTimestamp)); 
     }catch (Exception ex){ 
      //TODO: Log!! 
     } 

     Collections.sort(allParams, new NvpComparator()); 
     StringBuffer params = new StringBuffer(); 
     for(int i=0;i<allParams.size();i++) 
     { 
      NameValuePair nvp = allParams.get(i); 
      if (i>0) { 
       params.append("&"); 
      } 
      params.append(nvp.getName() + "=" + OAuth.percentEncode(nvp.getValue())); 
     } 
     String signatureBaseStringTemplate = "%s&%s&%s"; 
     String signatureBaseString = String.format(signatureBaseStringTemplate, 
       OAuth.percentEncode(method), 
       OAuth.percentEncode(url), 
       OAuth.percentEncode(params.toString())); 
     String compositeKey = OAuth.percentEncode(oAuthConsumerSecret)+"&"; 
     if(withToken) compositeKey+=OAuth.percentEncode(oAuthTokenSecret); 
     oAuthSignature = Signature.calculateRFC2104HMAC(signatureBaseString, compositeKey); 

     return oAuthSignature; 
    } 

    public String generatedAuthorization(List<NameValuePair> allParams){ 
     authorization = "OAuth "; 
     Collections.sort(allParams, new NvpComparator()); 
     for(NameValuePair nvm : allParams){ 
      authorization+=nvm.getName()+"="+OAuth.percentEncode(nvm.getValue())+", "; 
     } 
     authorization=authorization.substring(0,authorization.length()-2); 
     return authorization; 
    } 

} 

Erklären:
1. getTwitterServerTime
In oAuthTimestamp Sie nicht Ihre Zeit von Server benötigen, aber die Zeit eines Twitter-Server. Sie können diesen Parameter optimieren, wenn Sie immer Anfragen auf dem bestimmten Twitter-Server senden.

2. HeaderCreator.generatedSignature (...)
url - url logisch zu Twitter API
Methode - GET oder POST.Sie müssen immer "POST" verwenden
allParams - Parameter, von denen Sie wissen, dass sie eine Signatur generieren ("param_name", "param_value");
withToken - wenn Sie wissen, dass oAuthTokenSecret wahr ist. Sonst falsch.

3. HeaderCreator.generatedAuthorization (...)
Verwenden Sie diese Methode nach generatedSignature (...), um eine OAuth-Header-Zeichenfolge zu generieren.
allParams - Parameter, die Sie in generatedSignature (...) verwendet haben plus: Nonce, Signatur, Zeitstempel. Benutzen Sie immer:

allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce())); 
allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature())); 
allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp())); 


Jetzt können Sie es verwenden UnpackedRequest.OAuth1Request in Ihrer Bibliothek zu füllen.
Auch hier ein Beispiel, um Benutzer in SpringMVC ohne die Bibliothek zu authentifizieren:
Anfragen - Postanforderungen senden.

public class Requests { 
    public static String sendPost(String url, String urlParameters, Map<String, String> prop) throws Exception { 
     URL obj = new URL(url); 
     HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); 

     con.setRequestMethod("POST"); 
     if(prop!=null) { 
      for (Map.Entry<String, String> entry : prop.entrySet()) { 
       con.setRequestProperty(entry.getKey(), entry.getValue()); 
      } 
     } 
     con.setDoOutput(true); 
     DataOutputStream wr = new DataOutputStream(con.getOutputStream()); 
     wr.writeBytes(urlParameters); 
     wr.flush(); 
     wr.close(); 
     int responseCode = con.getResponseCode(); 
     BufferedReader in; 
     if(responseCode==200) { 
      in = new BufferedReader(
        new InputStreamReader(con.getInputStream())); 
     }else{ 
      in = new BufferedReader(
        new InputStreamReader(con.getErrorStream())); 
     } 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 
     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 

     return response.toString(); 
    } 
} 

twAuth (...) - setze sie in der Steuerung. Führen Sie es aus, wenn sich ein Benutzer auf Ihrer Website über Twitter authentifizieren möchte.

@RequestMapping(value = "/twauth", method = RequestMethod.GET) 
    @ResponseBody 
    public String twAuth(HttpServletResponse response) throws Exception{ 
     try { 
      String url = "https://api.twitter.com/oauth/request_token"; 

      List<NameValuePair> allParams = new ArrayList<NameValuePair>(); 
      allParams.add(new BasicNameValuePair("oauth_callback", "http://127.0.0.1:8080/twlogin")); 
      allParams.add(new BasicNameValuePair("oauth_consumer_key", "2YhNLyum1VY10UrWBMqBnatiT")); 
      allParams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1")); 
      allParams.add(new BasicNameValuePair("oauth_version", "1.0")); 

      HeaderCreator headerCreator = new HeaderCreator("RUesRE56vVWzN9VFcfA0jCBz9VkvkAmidXj8d1h2tS5EZDipSL"); 
      headerCreator.generatedSignature(url,"POST",allParams,false); 
      allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce())); 
      allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature())); 
      allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp())); 

      Map<String, String> props = new HashMap<String, String>(); 
      props.put("Authorization", headerCreator.generatedAuthorization(allParams)); 
      String twitterResponse = Requests.sendPost(url,"",props); 
      Integer indOAuthToken = twitterResponse.indexOf("oauth_token"); 
      String oAuthToken = twitterResponse.substring(indOAuthToken, twitterResponse.indexOf("&",indOAuthToken)); 

      response.sendRedirect("https://api.twitter.com/oauth/authenticate?" + oAuthToken); 
     }catch (Exception ex){ 
      //TODO: Log 
      throw new Exception(); 
     } 
     return "main"; 
    } 

twLogin (...) - setze sie in der Steuerung. Es ist ein Rückruf von Twitter.

@RequestMapping(value = "/twlogin", method = RequestMethod.GET) 
    public String twLogin(@RequestParam("oauth_token") String oauthToken, 
          @RequestParam("oauth_verifier") String oauthVerifier, 
          Model model, HttpServletRequest request){ 
     try { 
      if(oauthToken==null || oauthToken.equals("") || 
        oauthVerifier==null || oauthVerifier.equals("")) 
       return "main"; 

      String url = "https://api.twitter.com/oauth/access_token"; 

      List<NameValuePair> allParams = new ArrayList<NameValuePair>(); 
      allParams.add(new BasicNameValuePair("oauth_consumer_key", "2YhNLyum1VY10UrWBMqBnatiT")); 
      allParams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1")); 
      allParams.add(new BasicNameValuePair("oauth_token", oauthToken)); 
      allParams.add(new BasicNameValuePair("oauth_version", "1.0")); 
      NameValuePair oAuthVerifier = new BasicNameValuePair("oauth_verifier", oauthVerifier); 
      allParams.add(oAuthVerifier); 

      HeaderCreator headerCreator = new HeaderCreator("RUesRE56vVWzN9VFcfA0jCBz9VkvkAmidXj8d1h2tS5EZDipSL"); 
      headerCreator.generatedSignature(url,"POST",allParams,false); 
      allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce())); 
      allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature())); 
      allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp())); 
      allParams.remove(oAuthVerifier); 

      Map<String, String> props = new HashMap<String, String>(); 
      props.put("Authorization", headerCreator.generatedAuthorization(allParams)); 

      String twitterResponse = Requests.sendPost(url,"oauth_verifier="+oauthVerifier,props); 

      //Get user id 

      Integer startIndexTmp = twitterResponse.indexOf("user_id")+8; 
      Integer endIndexTmp = twitterResponse.indexOf("&",startIndexTmp); 
      if(endIndexTmp<=0) endIndexTmp = twitterResponse.length()-1; 
      Long userId = Long.parseLong(twitterResponse.substring(startIndexTmp, endIndexTmp)); 

      //Do what do you want... 

     }catch (Exception ex){ 
      //TODO: Log 
      throw new Exception(); 
     } 
    } 
+0

Dank eine so ausführliche Antwort zu teilen. –