授予UTL_MAIL.SEND凭据以绕过ORA-29278

时间:2014-10-03 20:18:01

标签: sql oracle email

我正在尝试使用UTL_MAIL.Send打包过程从PL / SQL程序发送电子邮件。但我收到以下错误:

  

ORA-29278:SMTP瞬态错误:421服务不可用

我在网上搜索,发现发生此错误是因为运行我的Oracle数据库的主机上没有SMTP服务。

现在,如果我想使用其他SMTP服务器,例如hotmail的“smtp.live.com”,我需要我的用户名和密码。

如何将我的密码输入UTL_MAIL.Send程序调用?

(根据我的理解,为了使用任何其他SMTP服务器,我必须提供我的用户名/密码)。我知道要使用UTL_MAIL包,我们使用初始化参数设置SMTP服务器,我们可以在“Sender”参数中给出用户名,但问题是我们应该在哪里提供密码?

2 个答案:

答案 0 :(得分:2)

基本上你必须使用"较低级别" UTL_SMTP包,以便发送远程SMTP服务器所需的各种SMTP邮件。

验证

来自Stefano Ghio's blog

 -- prepare base64 encoded username and password
 l_encoded_username := UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(username)));  
 l_encoded_password := UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(password)));

 -- Open connection and send EHLO and AUTH messages  
 l_conn := UTL_SMTP.open_connection(smtpHost, smtpPort);  
 UTL_SMTP.ehlo(l_conn, smtpHost);--DO NOT USE HELO  
 UTL_SMTP.command(l_conn, 'AUTH', 'LOGIN');  
 UTL_SMTP.command(l_conn, l_encoded_username);  
 UTL_SMTP.command(l_conn, l_encoded_password);  

这里的主要问题是您需要能够使用"权利"发送AUTH消息。服务器的身份验证方案。我不能特别对" smtp.live.com" 说,但根据服务器的配置,它们可能是不同的身份验证方案,例如{{1 }}和PLAINLOGIN,...通常(总是?)参数(DIGEST_MD5username)是base64编码的。

发送邮件

坏消息,因为您现在使用的是低级库,您必须自己实现SMTP protocol的客户端部分。来自上面的相同来源(由我自己编辑,只保留绝对最少的必要内容):

password

使用SSL / TLS

现在,对于非常坏消息:某些服务器需要安全连接。声称像UTL_SMTP.mail(l_conn, mailFrom); UTL_SMTP.rcpt(l_conn, rcptTo); [...] --start multi line message UTL_SMTP.open_data(l_conn); --prepare mail header UTL_SMTP.write_data(l_conn, 'To: ' || rcptTo || crlf); UTL_SMTP.write_data(l_conn, 'From: ' || mailFrom || crlf); UTL_SMTP.write_data(l_conn, 'Subject: ' || messageSubject || crlf); --include the message body UTL_SMTP.write_data(l_conn, messageBody || crlf || crlf); --send the email and close connection UTL_SMTP.close_data(l_conn); UTL_SMTP.quit(l_conn); 这样的东西。遗憾的是,仅从Oracle Database 11g第2版(11.2.0.2)开始支持UTL_SMTP.STARTTLS

如果您很幸运能够使用最新版本的Oracle,那么您应该编写类似的内容来打开与服务器的安全连接:

530 Must issue a STARTTLS command first

引用Oracle的文档:

  

SSL / TLS需要一个Oracle钱包,必须在OPEN_CONNECTION函数打开连接时指定。

请参阅相应的文档以查看how to create and manage wallet


几点读数:

答案 1 :(得分:0)

在网上找到了这个。看起来这些中的任何一个应该可以解决问题:

AUTH PLAIN

v_plain_string :=
     UTL_RAW.cast_to_varchar2(
        UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw('my_user_name'||chr(0)||'my_user_name'||chr(0)||'my_secret_password'))
    );

v_connection := UTL_SMTP.open_connection(:v_smtp_server);
UTL_SMTP.ehlo(v_connection, 'mydomain.com');    -- Must use EHLO  vs HELO
UTL_SMTP.command(v_connection, 'AUTH', 'PLAIN ' || v_plain_string);

AUTH LOGIN

v_username_b64 :=
    UTL_RAW.cast_to_varchar2(
        UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(:v_username))
    );
v_password_b64 :=
    UTL_RAW.cast_to_varchar2(
        UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(:v_password))
    );
v_connection := UTL_SMTP.open_connection(:v_smtp_server);
UTL_SMTP.ehlo(v_connection, 'mydomain.com');    -- Must use EHLO  vs HELO
UTL_SMTP.command(v_connection, 'AUTH', 'LOGIN');  -- should receive a 334 response, prompting for username
UTL_SMTP.command(v_connection, v_username_b64);   -- should receive a 334 response, prompting for password
UTL_SMTP.command(v_connection, v_password_b64);   -- should receive a 235 response, you are authenticated

我想当你谈到“发件人”参数时,你可能会引用电子邮件本身的“发件人”标题。