XOauth

2012-09-19 10 views
15

का उपयोग करके एंड्रॉइड में जावामाइल एपीआई javamail API (यदि उपलब्ध हो तो कोई अन्य मेलिंग सेवा भी) का उपयोग करके मुझे अपने ऐप के माध्यम से एक ईमेल भेजने की आवश्यकता है। समस्या यह है कि मैं उपयोगकर्ता को अपने username और password से नहीं पूछना चाहता हूं।XOauth

1) क्या यह संभव है के साथ JavaMail API/किसी भी अन्य मेल एपीआई

2) कैसे OAuth टोकन प्राप्त करने के लिए OAuth 2.0 उपयोग करने के लिए ??

3) वहाँ एक नमूना कोड पर पहले से शुद्ध

धन्यवाद उपलब्ध है।

पीएस: मैंने मेलिंग सेवाओं/एसएमटीपी अनुरोधों के साथ कभी भी काम नहीं किया है।

+0

जैवमेल में एसएएसएल कार्यान्वयन में गैर-एंड्रॉइड निर्भरता में इन अनुमतियों की भी आवश्यकता है। मेरा जवाब यहां देखें: http://stackoverflow.com/a/11830319/50913 – Malachi

+0

मुझे उस सड़क ब्लॉक पर पहुंचा है और आपने अपनी पोस्ट को पहले ही देखा है ... अंततः उपयोगकर्ता प्रमाण-पत्रों का उपयोग करके इसे पुराना तरीका बना दिया। – SKen

उत्तर

27

मैंने कुछ दिनों तक इसका शोध किया और मुझे एक समाधान मिला जो इस समय मेरे लिए काम कर रहा है। मुझे एंड्रॉइड खाता प्रबंधक से oauth2 टोकन मिलता है और फिर जावामेल का उपयोग करके एसएमटीपी के माध्यम से ईमेल भेजता है। विचार जावा उदाहरण यहाँ http://code.google.com/p/google-mail-oauth2-tools/wiki/JavaSampleCode पर हैं और इस जावा Xoauth उदाहरण यहाँ http://google-mail-xoauth-tools.googlecode.com/svn/trunk/java/com/google/code/samples/xoauth/XoauthAuthenticator.java

वहाँ Android के लिए JavaMail में कोई काम कर रहे SASL कार्यान्वयन है और asmack का उपयोग इतना काम कर रहा था मैं SASL का उपयोग नहीं किया पर आधारित है और मैं आदेश जारी ऊपर Xoauth उदाहरण में सीधे की तरह।

मैं इस

AccountManager am = AccountManager.get(this); 
Account me = ...; //You need to get a google account on the device, it changes if you have more than one 
am.getAuthToken(me, "oauth2:https://mail.google.com/", null, this, new OnTokenAcquired(), null); 

private class OnTokenAcquired implements AccountManagerCallback<Bundle>{ 
    @Override 
    public void run(AccountManagerFuture<Bundle> result){ 
     try{ 
      Bundle bundle = result.getResult(); 
      token = bundle.getString(AccountManager.KEY_AUTHTOKEN); 

     } catch (Exception e){ 
      Log.d("test", e.getMessage()); 
     } 
    } 
} 

तरह acount प्रबंधक से टोकन प्राप्त अगर यह काम करता है, तो आप टोकन में एक OAuth2 टोकन की है। मैं इस कोड

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.security.Provider; 
import java.security.Security; 
import java.util.Properties; 

import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.URLName; 
import javax.mail.Message; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 

import android.util.Log; 

import com.sun.mail.smtp.SMTPTransport; 
import com.sun.mail.util.BASE64EncoderStream; 

public class GMailOauthSender { 
private Session session; 


public SMTPTransport connectToSmtp(String host, int port, String userEmail, 
     String oauthToken, boolean debug) throws Exception { 

    Properties props = new Properties(); 
    props.put("mail.smtp.starttls.enable", "true"); 
    props.put("mail.smtp.starttls.required", "true"); 
    props.put("mail.smtp.sasl.enable", "false"); 
    session = Session.getInstance(props); 
    session.setDebug(debug); 


    final URLName unusedUrlName = null; 
    SMTPTransport transport = new SMTPTransport(session, unusedUrlName); 
    // If the password is non-null, SMTP tries to do AUTH LOGIN. 
    final String emptyPassword = null; 
    transport.connect(host, port, userEmail, emptyPassword); 

      byte[] response = String.format("user=%s\1auth=Bearer %s\1\1", userEmail, 
      oauthToken).getBytes(); 
    response = BASE64EncoderStream.encode(response); 

    transport.issueCommand("AUTH XOAUTH2 " + new String(response), 
      235); 

    return transport; 
} 

public synchronized void sendMail(String subject, String body, String user, 
     String oauthToken, String recipients) { 
    try { 

     SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 
       587, 
       user, 
       oauthToken, 
       true); 

     MimeMessage message = new MimeMessage(session); 
     DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain")); 
       message.setSender(new InternetAddress(user)); 
       message.setSubject(subject); 
       message.setDataHandler(handler); 
     if (recipients.indexOf(',') > 0) 
      message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients)); 
     else 
      message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients)); 
     smtpTransport.sendMessage(message, message.getAllRecipients()); 


    } catch (Exception e) { 
     Log.d("test", e.getMessage()); 
    } 

} 

मैं इस में सभी एक विशेषज्ञ पर नहीं कर रहा हूँ और मैं ऊपर के उदाहरण में जैसे किसी भी सुरक्षा प्रदाता का उपयोग नहीं किया में टोकन का उपयोग, यकीन नहीं है कि यह कैसे इस को प्रभावित करेगा लेकिन इसके लिए काम कर रहा है मुझे। उम्मीद है कि इससे मदद मिलती है और कोई मुझे बता सकता है कि इसमें कुछ गड़बड़ है: पी यह मेरा पहला जवाब है, इसलिए मुझे खेद है कि मैंने कुछ गलत किया है! https://developers.google.com/google-apps/gmail/xoauth2_protocol और http://developer.android.com/training/id-auth/authenticate.html

ऑप्स फिर से:

ऑप्स, कुछ अन्य प्रलेखन मैं इस्तेमाल किया भूल गया! आपको मेनिफेस्ट

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> 
+1

धन्यवाद @alex मैं इसे आज़माउंगा और आपको वापस प्राप्त करूंगा – SKen

+0

GAE: GAE + SMTP + OAuth + GMail के साथ ईमेल भेजने के लिए काम करता है - बिलिंग सक्षम होना आवश्यक है, लेकिन यह करने के लिए स्वतंत्र है। – eddyparkinson

+0

यह उत्तर मुझे एक एनपीई देता है जब 'sendMessage()' कहा जाता है, कोई विचार? :) – whitfin