Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
cmeeting
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
翟斌
cmeeting
Commits
2c51379b
提交
2c51379b
authored
8月 20, 2025
作者:
洪东保
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
微软邮箱参数加密
父级
a15e067f
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
108 行增加
和
437 行删除
+108
-437
src/main/java/com/cmeeting/email/AzureADEmailSender.java
+0
-145
src/main/java/com/cmeeting/email/EmailSender.java
+13
-14
src/main/java/com/cmeeting/email/GraphApiWithOkHttp2.java
+0
-85
src/main/java/com/cmeeting/email/QQMailSender.java
+0
-90
src/main/java/com/cmeeting/email/TestExchangeAndOauth2.java
+0
-103
src/main/java/com/cmeeting/util/RSAUtils.java
+90
-0
src/main/resources/application.yml
+5
-0
没有找到文件。
src/main/java/com/cmeeting/email/AzureADEmailSender.java
deleted
100644 → 0
浏览文件 @
a15e067f
package
com
.
cmeeting
.
email
;
import
com.azure.identity.ClientSecretCredential
;
import
com.azure.identity.ClientSecretCredentialBuilder
;
import
com.microsoft.graph.authentication.IAuthenticationProvider
;
import
com.microsoft.graph.authentication.TokenCredentialAuthProvider
;
import
com.microsoft.graph.models.*
;
import
com.microsoft.graph.requests.GraphServiceClient
;
import
okhttp3.MediaType
;
import
okhttp3.OkHttpClient
;
import
okhttp3.RequestBody
;
import
okhttp3.Response
;
import
java.io.*
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.LinkedList
;
public
class
AzureADEmailSender
{
public
static
void
main
(
String
[]
args
)
throws
IOException
{
//d65aa91b-05f4-42b2-902f-4d82ea5a2b93
//~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX
//74cc8acf-aacc-4514-9bbb-dc27ce3096bb
/**中集
* c06fe7cf-2a89-4099-9805-ce03031938f8
* wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u
* 18653b3e-03c7-499e-8baf-42ef06a814ef
*/
ClientSecretCredential
clientSecretCredential
=
new
ClientSecretCredentialBuilder
()
.
clientId
(
"d65aa91b-05f4-42b2-902f-4d82ea5a2b93"
)
.
clientSecret
(
"~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX"
)
.
tenantId
(
"74cc8acf-aacc-4514-9bbb-dc27ce3096bb"
)
.
build
();
final
TokenCredentialAuthProvider
tokenCredAuthProvider
=
new
TokenCredentialAuthProvider
(
Arrays
.
asList
(
"https://graph.microsoft.com/.default"
),
clientSecretCredential
);
System
.
out
.
println
(
"First Step Reached. "
);
buildDraftMessage
(
tokenCredAuthProvider
);
}
private
static
final
long
MB
=
1024
*
1024
;
//binzhai321@outlook.com
//cmeeting_assistant@cimc.com
private
static
final
String
SENDER_MAIL
=
"binzhai321@outlook.com"
;
private
static
final
String
RECIPIENT_MAIL
=
"binzhai321@outlook.com"
;
public
static
void
buildDraftMessage
(
TokenCredentialAuthProvider
authProvider
)
throws
IOException
{
GraphServiceClient
graphClient
=
GraphServiceClient
.
builder
().
authenticationProvider
(
authProvider
).
buildClient
();
Message
message
=
new
Message
();
message
.
subject
=
"Did you see last night's game?"
;
ItemBody
body
=
new
ItemBody
();
body
.
contentType
=
BodyType
.
HTML
;
body
.
content
=
"They were <b>awesome</b>!"
;
message
.
body
=
body
;
LinkedList
<
Recipient
>
toRecipientsList
=
new
LinkedList
<
Recipient
>();
Recipient
toRecipients
=
new
Recipient
();
EmailAddress
emailAddress
=
new
EmailAddress
();
emailAddress
.
address
=
RECIPIENT_MAIL
;
toRecipients
.
emailAddress
=
emailAddress
;
toRecipientsList
.
add
(
toRecipients
);
message
.
toRecipients
=
toRecipientsList
;
//构建草稿
Message
post
=
graphClient
.
users
(
SENDER_MAIL
).
messages
()
.
buildRequest
()
.
post
(
message
);
//构建附件
buildAttach
(
authProvider
,
post
);
//发送草稿邮件
graphClient
.
users
(
SENDER_MAIL
).
messages
(
post
.
id
)
.
send
()
.
buildRequest
()
.
post
();
}
private
static
void
buildAttach
(
IAuthenticationProvider
authProvider
,
Message
message
)
throws
IOException
{
File
file
=
new
File
(
"path"
);
FileInputStream
fileInputStream
=
new
FileInputStream
(
file
);
int
available
=
fileInputStream
.
available
();
if
(
available
>=
3
*
MB
)
{
//附件大于3M,使用大附件专用发送方法
bigAttach
(
authProvider
,
message
,
file
);
}
else
{
//附件小于3M,使用普通发送方法
commonAttach
(
authProvider
,
message
,
fileInputStream
);
}
}
public
static
byte
[]
toByteArray
(
InputStream
input
)
throws
IOException
{
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
();
byte
[]
buffer
=
new
byte
[
1024
*
4
];
int
n
=
0
;
while
(-
1
!=
(
n
=
input
.
read
(
buffer
)))
{
output
.
write
(
buffer
,
0
,
n
);
}
return
output
.
toByteArray
();
}
private
static
void
commonAttach
(
IAuthenticationProvider
authProvider
,
Message
message
,
FileInputStream
fileInputStream
)
throws
IOException
{
GraphServiceClient
graphClient
=
GraphServiceClient
.
builder
().
authenticationProvider
(
authProvider
).
buildClient
();
FileAttachment
attachment
=
new
FileAttachment
();
attachment
.
oDataType
=
"#microsoft.graph.fileAttachment"
;
attachment
.
name
=
"smile.pdf"
;
attachment
.
contentBytes
=
toByteArray
(
fileInputStream
);
graphClient
.
users
(
SENDER_MAIL
).
messages
(
message
.
id
).
attachments
()
.
buildRequest
()
.
post
(
attachment
);
}
public
static
void
bigAttach
(
IAuthenticationProvider
authProvider
,
Message
message
,
File
file
)
throws
IOException
{
GraphServiceClient
graphClient
=
GraphServiceClient
.
builder
().
authenticationProvider
(
authProvider
).
buildClient
();
FileInputStream
fileInputStream
=
new
FileInputStream
(
file
);
int
available
=
fileInputStream
.
available
();
AttachmentItem
attachmentItem
=
new
AttachmentItem
();
attachmentItem
.
attachmentType
=
AttachmentType
.
FILE
;
attachmentItem
.
name
=
"flower.pdf"
;
attachmentItem
.
size
=
(
long
)
available
;
UploadSession
uploadSession
=
graphClient
.
users
(
SENDER_MAIL
).
messages
(
message
.
id
).
attachments
()
.
createUploadSession
(
AttachmentCreateUploadSessionParameterSet
.
newBuilder
()
.
withAttachmentItem
(
attachmentItem
)
.
build
())
.
buildRequest
()
.
post
();
OkHttpClient
client
=
new
OkHttpClient
().
newBuilder
().
build
();
MediaType
mediaType
=
MediaType
.
parse
(
"application/octet-stream"
);
RequestBody
body
=
RequestBody
.
create
(
mediaType
,
file
);
okhttp3
.
Request
request
=
new
okhttp3
.
Request
.
Builder
()
.
url
(
uploadSession
.
uploadUrl
)
.
method
(
"PUT"
,
body
)
.
addHeader
(
"Content-Length"
,
String
.
valueOf
(
attachmentItem
.
size
))
.
addHeader
(
"Content-Range"
,
"bytes 0-"
+
(
attachmentItem
.
size
-
1
)
+
"/"
+
attachmentItem
.
size
)
.
addHeader
(
"Content-Type"
,
"application/octet-stream"
)
.
build
();
Response
response
=
client
.
newCall
(
request
).
execute
();
System
.
out
.
println
(
response
.
body
().
string
());
}
}
\ No newline at end of file
src/main/java/com/cmeeting/email/EmailSender.java
浏览文件 @
2c51379b
...
@@ -11,6 +11,7 @@ import com.cmeeting.exception.RobotBaseException;
...
@@ -11,6 +11,7 @@ import com.cmeeting.exception.RobotBaseException;
import
com.cmeeting.log.service.ProcessLogService
;
import
com.cmeeting.log.service.ProcessLogService
;
import
com.cmeeting.pojo.MeetEmailTemplate
;
import
com.cmeeting.pojo.MeetEmailTemplate
;
import
com.cmeeting.service.MeetEmailTemplateService
;
import
com.cmeeting.service.MeetEmailTemplateService
;
import
com.cmeeting.util.RSAUtils
;
import
com.cmeeting.util.RedisUtils
;
import
com.cmeeting.util.RedisUtils
;
import
com.cmeeting.vo.EmailPush
;
import
com.cmeeting.vo.EmailPush
;
import
com.cmeeting.vo.StatisticsEmailPush
;
import
com.cmeeting.vo.StatisticsEmailPush
;
...
@@ -48,27 +49,25 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -48,27 +49,25 @@ import java.util.concurrent.atomic.AtomicInteger;
public
class
EmailSender
{
public
class
EmailSender
{
@Value
(
"${email.sender}"
)
@Value
(
"${email.sender}"
)
private
String
SENDER
;
private
String
SENDER
;
// @Value("${email.sender-pwd}")
// private String EMAIL_PWD;
@Value
(
"${email.push-switch}"
)
@Value
(
"${email.push-switch}"
)
private
Boolean
pushSwitch
;
private
Boolean
pushSwitch
;
@Value
(
"${email.environment}"
)
@Value
(
"${email.environment}"
)
private
String
environment
;
private
String
environment
;
@Value
(
"${email.test-receiver}"
)
@Value
(
"${email.test-receiver}"
)
private
String
testReceiver
;
private
String
testReceiver
;
@Value
(
"${email.microsoft.clientId}"
)
private
String
clientId
;
@Value
(
"${email.microsoft.clientSecret}"
)
private
String
clientSecret
;
@Value
(
"${email.microsoft.tenantId}"
)
private
String
tenantId
;
private
String
CLIENT_ID
=
"c06fe7cf-2a89-4099-9805-ce03031938f8"
;
private
String
CLIENT_SECRET
=
"wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u"
;
private
String
TENANT_ID
=
"18653b3e-03c7-499e-8baf-42ef06a814ef"
;
@Resource
@Resource
private
ProcessLogService
processLogService
;
private
ProcessLogService
processLogService
;
@Resource
@Resource
private
MeetEmailTemplateService
meetEmailTemplateService
;
private
MeetEmailTemplateService
meetEmailTemplateService
;
private
static
final
Integer
MAX_RETRY
=
3
;
private
static
final
Integer
MAX_RETRY
=
3
;
@Resource
private
RedisUtils
redisUtils
;
/**
/**
* 发送邮件,带附件
* 发送邮件,带附件
...
@@ -110,9 +109,9 @@ public class EmailSender {
...
@@ -110,9 +109,9 @@ public class EmailSender {
while
(
retryCount
.
intValue
()
<
MAX_RETRY
&&
isSent
!=
null
&&
!
isSent
)
{
while
(
retryCount
.
intValue
()
<
MAX_RETRY
&&
isSent
!=
null
&&
!
isSent
)
{
try
{
try
{
ClientSecretCredential
clientSecretCredential
=
new
ClientSecretCredentialBuilder
()
ClientSecretCredential
clientSecretCredential
=
new
ClientSecretCredentialBuilder
()
.
clientId
(
CLIENT_ID
)
.
clientId
(
RSAUtils
.
decrypt
(
clientId
)
)
.
clientSecret
(
CLIENT_SECRET
)
.
clientSecret
(
RSAUtils
.
decrypt
(
clientSecret
)
)
.
tenantId
(
TENANT_ID
)
.
tenantId
(
RSAUtils
.
decrypt
(
tenantId
)
)
.
build
();
.
build
();
try
{
try
{
TokenRequestContext
context
=
new
TokenRequestContext
()
TokenRequestContext
context
=
new
TokenRequestContext
()
...
@@ -211,9 +210,9 @@ public class EmailSender {
...
@@ -211,9 +210,9 @@ public class EmailSender {
while
(
retryCount
.
intValue
()
<
MAX_RETRY
&&
!
isSent
)
{
while
(
retryCount
.
intValue
()
<
MAX_RETRY
&&
!
isSent
)
{
try
{
try
{
ClientSecretCredential
clientSecretCredential
=
new
ClientSecretCredentialBuilder
()
ClientSecretCredential
clientSecretCredential
=
new
ClientSecretCredentialBuilder
()
.
clientId
(
CLIENT_ID
)
.
clientId
(
RSAUtils
.
decrypt
(
clientId
)
)
.
clientSecret
(
CLIENT_SECRET
)
.
clientSecret
(
RSAUtils
.
decrypt
(
clientSecret
)
)
.
tenantId
(
TENANT_ID
)
.
tenantId
(
RSAUtils
.
decrypt
(
tenantId
)
)
.
build
();
.
build
();
try
{
try
{
TokenRequestContext
context
=
new
TokenRequestContext
().
addScopes
(
"https://graph.microsoft.com/.default"
);
TokenRequestContext
context
=
new
TokenRequestContext
().
addScopes
(
"https://graph.microsoft.com/.default"
);
...
...
src/main/java/com/cmeeting/email/GraphApiWithOkHttp2.java
deleted
100644 → 0
浏览文件 @
a15e067f
package
com
.
cmeeting
.
email
;
import
com.azure.core.credential.TokenRequestContext
;
import
com.azure.identity.ClientSecretCredential
;
import
com.azure.identity.ClientSecretCredentialBuilder
;
import
okhttp3.*
;
import
java.io.IOException
;
public
class
GraphApiWithOkHttp2
{
static
String
CLIENT_ID
=
"d65aa91b-05f4-42b2-902f-4d82ea5a2b93"
;
static
String
TENANT_ID
=
"74cc8acf-aacc-4514-9bbb-dc27ce3096bb"
;
// or "common" for multi-tenant apps
static
String
CLIENT_SECRET
=
"~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX"
;
//"cmeeting_assistant@cimc.com"
//"binzhai321@outlook.com"
private
static
final
String
USER_EMAIL
=
"cmeeting_assistant@cimc.com"
;
// 发送邮件的用户
public
static
void
main
(
String
[]
args
)
throws
IOException
{
/**中集:
* c06fe7cf-2a89-4099-9805-ce03031938f8
* wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u
* 18653b3e-03c7-499e-8baf-42ef06a814ef
*/
ClientSecretCredential
credential
=
new
ClientSecretCredentialBuilder
()
.
clientId
(
"c06fe7cf-2a89-4099-9805-ce03031938f8"
)
.
clientSecret
(
"wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u"
)
.
tenantId
(
"18653b3e-03c7-499e-8baf-42ef06a814ef"
)
.
build
();
// 1. 获取 Access Token
String
token
=
credential
.
getToken
(
new
TokenRequestContext
()
.
addScopes
(
"https://graph.microsoft.com/.default"
))
.
block
().
getToken
();
System
.
out
.
println
(
"获取到的令牌: "
+
token
);
// String token1 ="EwBYBMl6BAAUBKgm8k1UswUNwklmy2v7U/S+1fEAAUa0jd3QNQBdqTy9ZwEaLPqqapU5zHFRz4XvGqbI7jN7x01mEvBtCSFgYtNiSOEb5s1UwLxl6HwlHFqfJsqDsoCicvnlqCWjsaR/4wPZgXxd+pBhHRSPl+tJcSzz2NJB+dy81wHcSaU4bRxCIgoU7MtrW2ak9DhGisnK4/vxHkzxuIjHe9IDOZBzwzAtTZhycWRoAtuQrC1iu/kuKGJaU9noNjsOwfHUaXRz68g6niSdPT8P6zOa2vlOHjhXh478ms1PhqKeTkS+nkTurT2Gc5qRJviICiiAlK4BlxV70tOA6xEtl2ApXOrfFr+rlv4pASmPewtbdkTHnpP3H0R9L0kQZgAAEF4HO14XaFxPCdIqniVBvSkgA75wLsTuUZragTXGu71SV7ccLi26nZ+9KZlulf8dAlj/NEdheqtdEHb+BOLknQoXFEJ0UNj6PLkczzHfV3Yr5zlXJICwb3yI9vrFTUCb555ux/P904vXCY900UNgX81gBIYJQIJtOCURDAcHWtxyWvfNlkr17fKgnX5KdDyec6JK9tgzPi62LlqhDcoR/W/4MTCZhfJRlZgdYkI52pQSbDJItR6W7xfZguXPgKRHVcZJTzlybtOW0kbrfv96CKrryKzGeRjZyEcov1U3VjAoBUllgi3+LdIFK86aojMuBP+v5PvRq81qZS2q5roIRJD5zydu1selrpwhrZjm2nupDxHGjvfj2TVZJlz1zGYsVYrSRz2+st+2UbZagR1fbPRX2GilTfDyN05HV//LrfdrddbffMImxY2M8D9iQZFSjBYSFa20S9Vs9/yj08M9ljwiJifHGjX2o/arR63SWe3pbga26EC+j8JaBemhAhPsu91xW4o7+j/xEUadXR2NDbuogMq+MeINKe3PqAAFeTva1ZWZF5p3oGVIQKL4pcQFA9xEwopoN+vSeHDuAOvTFQ/4PukxicJdFTiaZquGeQMF0sLFvLdddpvS3Xaf17fPxjMUlMGcjYQ8gK5XG5wzjR8Up4MZZyX3xiK/hccGOp5pwi8WAN5cVmTKZOSXTkHUGEQT4rcGUYTPduHYMjjrVpzffpnmqfO92VA7a7fuYqXKp3NPikv17s6PTVr6b4+24AP8u3MEhDHU2YjaMuFR3jBUYLxtm443Gn58MC7oYrmQIVN2VYJrxADgStqpE+3nUCyKajmF0q5U+LUI1cCYnOKgmAkrpN71qlB9GeQLLQDJytG2sg64NG/h3CN1SseudSYtmqM3XUURSsztB9dNL7xmHQAcEBYMVjec5N5jHLhIs48rxAqI/WAJ/2RFKWgJIeCUJ8v4oQYEI9lAlWgReVhrjcNxRsbuVDFFwU7cTSeY9bJzxSX5kWJ8TXr/Q/SELEViUVCz10Cw/sOtm4urke538R4yXlR1wfMk3S86xlOfc3HJ6Iz7hi1h2fovWA9T1ceFWQM=";
// 2. 使用 OkHttp 发送邮件
sendEmail
(
token
);
}
// 使用 Graph API 发送邮件
private
static
void
sendEmail
(
String
accessToken
)
throws
IOException
{
OkHttpClient
client
=
new
OkHttpClient
();
// 构建邮件内容 (JSON 格式)
String
emailJson
=
"{\n"
+
" \"message\": {\n"
+
" \"subject\": \"Test Email\",\n"
+
" \"body\": {\n"
+
" \"contentType\": \"Text\",\n"
+
" \"content\": \"This is a test email.\"\n"
+
" },\n"
+
" \"toRecipients\": [\n"
+
" {\n"
+
" \"emailAddress\": {\n"
+
" \"address\": \"binzhai321@outlook.com\"\n"
+
" }\n"
+
" }\n"
+
" ]\n"
+
" }\n"
+
"}"
;
// 构建请求
Request
request
=
new
Request
.
Builder
()
.
url
(
"https://graph.microsoft.com/v1.0/users/"
+
USER_EMAIL
+
"/sendMail"
)
.
post
(
RequestBody
.
create
(
MediaType
.
parse
(
"application/json"
),
emailJson
))
.
addHeader
(
"authorization"
,
"Bearer "
+
accessToken
)
.
addHeader
(
"Content-Type"
,
"application/json"
)
.
build
();
// 发送请求
try
(
Response
response
=
client
.
newCall
(
request
).
execute
())
{
if
(
response
.
isSuccessful
())
{
System
.
out
.
println
(
"Email sent successfully!"
);
}
else
{
System
.
err
.
println
(
"Failed to send email: "
+
response
.
code
()
+
" - "
+
response
.
message
());
System
.
err
.
println
(
response
.
body
().
string
());
// 打印错误详情
}
}
}
}
src/main/java/com/cmeeting/email/QQMailSender.java
deleted
100644 → 0
浏览文件 @
a15e067f
package
com
.
cmeeting
.
email
;
import
javax.activation.DataHandler
;
import
javax.activation.DataSource
;
import
javax.activation.FileDataSource
;
import
javax.mail.*
;
import
javax.mail.internet.*
;
import
java.util.Properties
;
public
class
QQMailSender
{
public
static
void
sendEmailWithAttachment
(
String
toEmail
,
String
filePath
)
{
// 发件人邮箱和授权码(不是密码)
String
from
=
"1960771676@qq.com"
;
String
password
=
"iaietlvcipyedjia"
;
// QQ邮箱的授权码
// QQ邮箱SMTP服务器设置
String
host
=
"smtp.qq.com"
;
// 设置属性
Properties
props
=
new
Properties
();
props
.
put
(
"mail.smtp.auth"
,
"true"
);
props
.
put
(
"mail.smtp.starttls.enable"
,
"true"
);
// 使用STARTTLS安全连接
props
.
put
(
"mail.smtp.host"
,
host
);
props
.
put
(
"mail.smtp.port"
,
"587"
);
// QQ邮箱的端口
// 获取Session对象
Session
session
=
Session
.
getInstance
(
props
,
new
Authenticator
()
{
protected
PasswordAuthentication
getPasswordAuthentication
()
{
return
new
PasswordAuthentication
(
from
,
password
);
}
});
try
{
// 创建邮件消息
Message
message
=
new
MimeMessage
(
session
);
// 设置发件人
message
.
setFrom
(
new
InternetAddress
(
from
));
// 设置收件人
message
.
setRecipients
(
Message
.
RecipientType
.
TO
,
InternetAddress
.
parse
(
toEmail
));
// 设置邮件主题
message
.
setSubject
(
"测试发送带附件的邮件"
);
// 创建消息体部分
BodyPart
messageBodyPart
=
new
MimeBodyPart
();
// 设置消息体内容
messageBodyPart
.
setText
(
"这是一封测试邮件,包含附件。"
);
// 创建多部分消息
Multipart
multipart
=
new
MimeMultipart
();
// 设置文本消息部分
multipart
.
addBodyPart
(
messageBodyPart
);
// 添加附件部分
messageBodyPart
=
new
MimeBodyPart
();
DataSource
source
=
new
FileDataSource
(
filePath
);
messageBodyPart
.
setDataHandler
(
new
DataHandler
(
source
));
messageBodyPart
.
setFileName
(
source
.
getName
());
multipart
.
addBodyPart
(
messageBodyPart
);
// 设置完整消息
message
.
setContent
(
multipart
);
// 发送邮件
Transport
.
send
(
message
);
System
.
out
.
println
(
"邮件发送成功!"
);
}
catch
(
MessagingException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
void
main
(
String
[]
args
)
{
// 收件人邮箱
String
toEmail
=
"1960771676@qq.com"
;
// 本地文件路径
String
filePath
=
"D:\\5397460824645048220.docx"
;
// 发送邮件
sendEmailWithAttachment
(
toEmail
,
filePath
);
}
}
\ No newline at end of file
src/main/java/com/cmeeting/email/TestExchangeAndOauth2.java
deleted
100644 → 0
浏览文件 @
a15e067f
package
com
.
cmeeting
.
email
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.base.Preconditions
;
import
microsoft.exchange.webservices.data.core.ExchangeService
;
import
microsoft.exchange.webservices.data.core.enumeration.misc.ConnectingIdType
;
import
microsoft.exchange.webservices.data.core.enumeration.misc.TraceFlags
;
import
microsoft.exchange.webservices.data.core.enumeration.property.BodyType
;
import
microsoft.exchange.webservices.data.core.enumeration.property.Importance
;
import
microsoft.exchange.webservices.data.core.request.HttpWebRequest
;
import
microsoft.exchange.webservices.data.core.service.item.EmailMessage
;
import
microsoft.exchange.webservices.data.credential.ExchangeCredentials
;
import
microsoft.exchange.webservices.data.misc.ImpersonatedUserId
;
import
microsoft.exchange.webservices.data.property.complex.EmailAddress
;
import
microsoft.exchange.webservices.data.property.complex.MessageBody
;
import
org.apache.commons.httpclient.HttpClient
;
import
org.apache.commons.httpclient.methods.PostMethod
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.net.URISyntaxException
;
import
java.util.Map
;
public
class
TestExchangeAndOauth2
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
mailAddress
=
"cmeeting_assistant@cimc.com"
;
String
tenant_id
=
"8653b3e-03c7-499e-8baf-42ef06a814ef"
;
String
client_id
=
"c06fe7cf-2a89-4099-9805-ce03031938f8"
;
String
client_secret
=
"wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u"
;
//注意不是密钥的id
String
scope
=
"https://outlook.office365.com/.default"
;
String
url
=
"https://login.microsoftonline.com/"
+
tenant_id
+
"/oauth2/v2.0/token"
;
// String scope = "https://partner.outlook.cn/.default";//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址
// String url = "https://login.partner.microsoftonline.cn/" + tenant_id + "/oauth2/v2.0/token";//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址
HttpClient
httpClient
=
new
HttpClient
();
PostMethod
postMethod
=
new
PostMethod
(
url
);
postMethod
.
addRequestHeader
(
"accept"
,
"*/*"
);
postMethod
.
addRequestHeader
(
"connection"
,
"Keep-Alive"
);
postMethod
.
addRequestHeader
(
"Content-Type"
,
"application/x-www-form-urlencoded;charset=GBK"
);
//必须设置下面这个Header
postMethod
.
addRequestHeader
(
"User-Agent"
,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"
);
//添加请求参数
postMethod
.
addParameter
(
"grant_type"
,
"client_credentials"
);
postMethod
.
addParameter
(
"client_id"
,
client_id
);
postMethod
.
addParameter
(
"client_secret"
,
client_secret
);
postMethod
.
addParameter
(
"scope"
,
scope
);
String
token
=
""
;
try
{
int
code
=
httpClient
.
executeMethod
(
postMethod
);
String
resBody
=
postMethod
.
getResponseBodyAsString
();
if
(
code
==
200
)
{
Map
<
String
,
Object
>
map
=
JSON
.
parseObject
(
resBody
,
Map
.
class
);
token
=
(
String
)
map
.
get
(
"access_token"
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
finally
{
postMethod
.
releaseConnection
();
}
ExchangeService
service
=
new
ExchangeService
();
service
.
setCredentials
(
new
OAuth2Credentials
(
token
));
service
.
setTraceEnabled
(
true
);
service
.
traceMessage
(
TraceFlags
.
EwsRequest
,
"office365"
);
service
.
setImpersonatedUserId
(
new
ImpersonatedUserId
(
ConnectingIdType
.
SmtpAddress
,
mailAddress
));
service
.
setUrl
(
new
URI
(
"https://outlook.office365.com/ews/exchange.asmx"
));
//service.setUrl(new URI("https://partner.outlook.cn/ews/exchange.asmx"));//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址
service
.
getHttpHeaders
().
put
(
"X-AnchorMailbox"
,
mailAddress
);
EmailMessage
msg
=
new
EmailMessage
(
service
);
msg
.
setFrom
(
new
EmailAddress
(
"mailAddress"
,
mailAddress
));
msg
.
getToRecipients
().
add
(
new
EmailAddress
(
"收件人邮箱昵称"
,
"binzhai321@outlook.com"
));
msg
.
setSubject
(
"邮件oauth2测试"
);
MessageBody
messageBody
=
new
MessageBody
();
messageBody
.
setBodyType
(
BodyType
.
Text
);
messageBody
.
setText
(
"哈哈哈哈"
);
msg
.
setBody
(
messageBody
);
msg
.
setImportance
(
Importance
.
Normal
);
msg
.
send
();
}
static
class
OAuth2Credentials
extends
ExchangeCredentials
{
private
String
accessToken
;
public
OAuth2Credentials
(
String
accessToken
)
{
Preconditions
.
checkNotNull
(
accessToken
);
this
.
accessToken
=
accessToken
;
}
@Override
public
void
prepareWebRequest
(
HttpWebRequest
client
)
throws
URISyntaxException
{
super
.
prepareWebRequest
(
client
);
if
(
client
.
getHeaders
()
!=
null
)
client
.
getHeaders
().
put
(
"Authorization"
,
"Bearer "
+
accessToken
);
}
}
}
src/main/java/com/cmeeting/util/RSAUtils.java
0 → 100644
浏览文件 @
2c51379b
package
com
.
cmeeting
.
util
;
import
org.springframework.stereotype.Component
;
import
javax.crypto.Cipher
;
import
java.security.*
;
import
java.security.spec.PKCS8EncodedKeySpec
;
import
java.security.spec.X509EncodedKeySpec
;
import
java.util.Base64
;
@Component
public
class
RSAUtils
{
private
static
final
String
PUBLIC_KEY_STR
=
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANZDOxNiSomQhsqwo56Psi257aHCYTCxpKUdGBp7NRigeuy80ppGEn1CFKx9hK9q/x4WR9RGU9eyCpP5QzyA+EcCAwEAAQ=="
;
private
static
final
String
PRIVATE_KEY_STR
=
"MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA1kM7E2JKiZCGyrCjno+yLbntocJhMLGkpR0YGns1GKB67LzSmkYSfUIUrH2Er2r/HhZH1EZT17IKk/lDPID4RwIDAQABAkAW/xxGFlSdsy9kbdUB3bZoBf6lT/GSgl6Dgj3mCbdHLy/sW8rJ/KYy5+wRpTSYVQBgWbRNMh6yeDaFD18lxZUBAiEA9hkCypO7k3nGzfe3dcSYptXprjSsoZsjVLoGsYJcRMECIQDe4kt+02P73QtdEXX7NUzALQVXygVtpccWCFF6nH3XBwIgEepiNKMqnaLY4TeuaGlmf4bFG0SEaMNlgA6G3DdURkECIQCPLkabeccwRIcJSa9GKq5cgk99Xw1vq+CiOcPGBYQdvwIhAJIXeBm6aeEj7yqWFsS2nVgnTppnMLZmFK8UcGC1EOFn"
;
public
static
void
generate
()
{
try
{
KeyPairGenerator
kp
=
KeyPairGenerator
.
getInstance
(
"RSA"
);
kp
.
initialize
(
512
);
// 要是需要2048的秘钥的话就修改一下参数
KeyPair
keyPair
=
kp
.
generateKeyPair
();
PublicKey
publicKey
=
keyPair
.
getPublic
();
System
.
out
.
println
(
"公钥为:"
+
new
String
(
Base64
.
getEncoder
().
encode
(
publicKey
.
getEncoded
())));
PrivateKey
privateKey
=
keyPair
.
getPrivate
();
System
.
out
.
println
(
"私钥为:"
+
new
String
(
Base64
.
getEncoder
().
encode
(
privateKey
.
getEncoded
())));
}
catch
(
NoSuchAlgorithmException
e
)
{
e
.
printStackTrace
();
}
}
// ChatId-87641da-sda==1513538437-问题
public
static
String
encrypt
(
String
sendMsg
)
{
String
strKey
=
null
;
// 公钥字符串,这里直接赋值了,当然一般不会这么写,把公钥放在一个数据文件或者配置里面去获取
try
{
// 把公钥字符串转换成对象
byte
[]
publicKeyBy
=
Base64
.
getDecoder
().
decode
(
PUBLIC_KEY_STR
.
getBytes
());
KeyFactory
keyFactory
=
KeyFactory
.
getInstance
(
"RSA"
);
PublicKey
publicKey
=
keyFactory
.
generatePublic
(
new
X509EncodedKeySpec
(
publicKeyBy
));
// 以上获得的PublicKey可以固化下来,只要秘钥不变,就可以一直使用,但是下面的cipherPublic 不要固化!因为他不是线程安全的,如果使用同一个cipherPublic 并发访问时可能会抛出异常javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
Cipher
cipherPublic
=
Cipher
.
getInstance
(
"RSA"
);
// 设置为加密模式并设置公钥
cipherPublic
.
init
(
Cipher
.
ENCRYPT_MODE
,
publicKey
);
// 定义一个发送的数据
// 获得加密的byte[]
byte
[]
encryptByte
=
cipherPublic
.
doFinal
(
sendMsg
.
toString
().
getBytes
(
"UTF-8"
));
// 转变成字符串以进行传输
strKey
=
Base64
.
getEncoder
().
encodeToString
(
encryptByte
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
strKey
;
}
// Ie2v8fu96HCU2Ls0YpdXy4kxSipp6ptdJUbr/5xzFQpc9sUIWjq5J4x6OzBXwoumhCC3/vYM/Wwo5Ik8PcjA0A==
public
static
String
decrypt
(
String
encryptReceiveMsg
)
{
String
receiveMsg
=
null
;
// 私钥字符串,这里直接赋值了,同样的,可以把私钥放在一个数据文件或者配置里面去获取
// 刚才我们获得的加密数据,一般通过各种传输途径接收到
try
{
// 把私钥字符串转换成对象
byte
[]
privateKeyBy
=
Base64
.
getDecoder
().
decode
(
PRIVATE_KEY_STR
.
getBytes
());
KeyFactory
keyFactory
=
KeyFactory
.
getInstance
(
"RSA"
);
PrivateKey
privateKey
=
keyFactory
.
generatePrivate
(
new
PKCS8EncodedKeySpec
(
privateKeyBy
));
// 同样的,可以固化cipherPrivate ,但是不能固化cipherPrivate,因为它不是线程安全的
Cipher
cipherPrivate
=
Cipher
.
getInstance
(
"RSA"
);
// 设置为解密模式并设置私钥
cipherPrivate
.
init
(
Cipher
.
DECRYPT_MODE
,
privateKey
);
// 进行解密
byte
[]
decryptByte
=
cipherPrivate
.
doFinal
(
Base64
.
getDecoder
().
decode
(
encryptReceiveMsg
.
replace
(
" +"
,
"+"
)));
// 转换成字符串
receiveMsg
=
new
String
(
decryptByte
,
"UTF-8"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
receiveMsg
;
}
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
decrypt
(
encrypt
(
"c06fe7cf-2a89-4099-9805-ce03031938f8"
)));
}
}
src/main/resources/application.yml
浏览文件 @
2c51379b
...
@@ -107,6 +107,10 @@ email:
...
@@ -107,6 +107,10 @@ email:
push-switch
:
true
#邮件推送总开关,高优先级
push-switch
:
true
#邮件推送总开关,高优先级
environment
:
test
#test推给本公司人员,prod推给用户
environment
:
test
#test推给本公司人员,prod推给用户
test-receiver
:
hongdongbao@chatbot.cn
#用于测试的收方邮箱
test-receiver
:
hongdongbao@chatbot.cn
#用于测试的收方邮箱
microsoft
:
clientId
:
'
rNvsNtIQTUAD7aYik9/1LDpfO+XbM4nuPkpf131H8vHfJg7Uj7HxJJcHFbtmO4uWagelhTsOTSx2PDqjeuqiYw=='
clientSecret
:
'
DERmPlHbjiN4rjIFHvpe+OypNRCuSwLe/MBy56EFtI7FkzHfOnVjMdCTRG/CmybBBfha6geFbijC6ymeMVSSeg=='
tenantId
:
'
dFSC/Jg4ibKnmKWCofo1KfR5IdsvHEHYiAE0iehpiyj0rzes8BRBzvQAu2rjG8SAm8VQetE+sLNvxObI8vq5iA=='
llm
:
llm
:
api-addr
:
${LLM_API_ADDR}
api-addr
:
${LLM_API_ADDR}
...
@@ -116,6 +120,7 @@ llm:
...
@@ -116,6 +120,7 @@ llm:
aec
:
aec
:
key
:
biaopin123456789
key
:
biaopin123456789
ldap
:
ldap
:
url
:
'
ldap://10.52.3.20/'
url
:
'
ldap://10.52.3.20/'
base
:
'
CN=AIGC,OU=数据网络中心,OU=集团公司,OU=集团总部,OU=无HR信息人员,OU=特殊邮箱,DC=cimc,DC=com'
base
:
'
CN=AIGC,OU=数据网络中心,OU=集团公司,OU=集团总部,OU=无HR信息人员,OU=特殊邮箱,DC=cimc,DC=com'
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论