2015-10-10 19 views
15

Tôi có một trường hợp sử dụng để xác thực yêu cầu OAuth1 được ký bằng Khóa riêng RSA và được xác minh ở cuối máy chủ bằng khóa công cộng RSA.Xác minh yêu cầu đã ký OAuth1a bằng cách sử dụng Twitter joauth với RSA-SHA1?

Tôi tìm thấy thư viện này từ Twitter giúp chúng tôi xác thực/xác minh yêu cầu đã ký của Oauth. https://github.com/twitter/joauth

Tôi muốn tận dụng thư viện này để xác minh yêu cầu từ phương thức hành động Jersey hoặc Spring MVC. Yêu cầu từ khách hàng sẽ được ký bằng cách sử dụng khóa riêng. Cuối cùng tôi sẽ sử dụng khóa công khai của khách hàng để xác minh yêu cầu. có nghĩa là RSA-SHA1.

Twitter joauth dường như là hữu ích nhưng tôi thiếu mã đó sẽ chuyển HttpServletRequest để OAuthRequest

Thư viện đọc cho tôi tập tin cho thấy đây là cơ sở nhưng tôi không thể tìm thấy một mã nào javax.servlet.http.HttpServletRequest ->com.twitter.joauth.OAuthRequest chuyển đổi.

Xác minh yêu cầu xảy ra trong phương thức xác minh có chữ ký sau.

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

Thứ hai tôi cũng muốn biết cách nào phù hợp nhất để sử dụng/đọc khóa công khai RSA bằng twitter joauth khi phương thức xác minh nhận tham số chuỗi?

+0

Bạn đang sử dụng phiên bản JOAuth nào? – Val

Trả lời

1

Tôi chưa bao giờ sử dụng bất kỳ thư viện nào để xác thực người dùng qua Twitter. Nhưng tôi vừa xem trong UnpackedRequest.OAuth1Request. Bạn có thể tạo một thể hiện của lớp này bằng cách điền vào tất cả các tham số. Tôi đã viết trình tạo Tiêu đề Twitter OAuth, vì vậy bạn chỉ có thể sử dụng nó để điền các thông số đó hoặc gửi yêu cầu POST trực tiếp mà không cần thư viện.

Dưới đây là tất cả các lớp bạn cần:

Chữ ký - để tạo Chữ ký OAuth.

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 - để sắp xếp các thông số bạn cần trong tiêu đề.

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 - để mã hóa URL.

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

HeaderCreator - để tạo ra tất cả các thông số cần thiết và tạo ra một param tiêu đề OAuth.

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; 
    } 

} 

Giải thích:
1. getTwitterServerTime
Trong oAuthTimestamp bạn không cần nhiều thời gian của bạn của máy chủ nhưng thời gian của một máy chủ Twitter. Bạn có thể tối ưu hóa nó để lưu tham số này nếu bạn luôn gửi yêu cầu trong máy chủ Twitter nhất định.

2. HeaderCreator.generatedSignature (...)
url - logic URL để twitter API
phương pháp - GET hoặc POST.Bạn phải luôn sử dụng "POST"
allParams - Tham số mà bạn biết để tạo chữ ký ("param_name", "param_value");
withToken - nếu bạn biết oAuthTokenSecret đã đúng. Nếu không thì sai.

3. HeaderCreator.generatedAuthorization (...)
Sử dụng phương pháp này sau khi tạoSignature (...) để tạo chuỗi tiêu đề OAuth.
allParams - là các tham số mà bạn đã sử dụng trong generatedSignature (...) cộng: nonce, signature, timestamp. Luôn luôn sử dụng:

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


Bây giờ bạn có thể sử dụng nó để điền UnpackedRequest.OAuth1Request trong thư viện của bạn.
Cũng ở đây một ví dụ để xác thực người dùng trong SpringMVC mà không cần thư viện:
Yêu cầu - để gửi yêu cầu đăng.

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 (...) - đặt trong bộ điều khiển của bạn. Thực hiện nó khi người dùng muốn xác thực trong trang web của bạn thông qua Twitter.

@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 (...) - đặt trong bộ điều khiển của bạn. Đó là gọi lại từ 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

Nhờ chia sẻ câu trả lời phức tạp như vậy. –

Các vấn đề liên quan