Apache James数据库存储用户信息的密码加密问题

2024-03-22 22:20

本文主要是介绍Apache James数据库存储用户信息的密码加密问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目场景

Apache James邮件服务器使用数据库来存储用户信息的密码加密问题:

  1. 将James的用户改为数据库存储
  2. James密码是如何加密验证的

1.将James的用户改为数据库存储

1、修改存储方式

找到james-2.3.2\apps\james\SAR-INF\config.xml

找到<users-store>标签,注释掉原来文件存储的方式,改为数据库的方式

maildb:是后面配置的数据源名称

mail_users:是存储用户信息的表名

<users-store><!-- 注释掉原来文件存储的方式 --><!--<repository name="LocalUsers" class="org.apache.james.userrepository.UsersFileRepository"><destination URL="file://var/users/"/></repository>--><!-- 改为数据库的方式 --><repository name="LocalUsers" class="org.apache.james.userrepository.JamesUsersJdbcRepository" destinationURL="db://maildb/mail_users"><sqlFile>file://conf/sqlResources.xml</sqlFile></repository></users-store>

 2.、配置数据库信息

找到<data-source>标签,根据具体数据库类型进行配置,下面已国产达梦数据库为例

maildb:数据源名称 

<data-source name="maildb" class="org.apache.james.util.dbcp.JdbcDataSource"><driver>dm.jdbc.driver.DmDriver</driver><dburl>jdbc:dm://127.0.0.1:5236/test_mail</dburl><user>test</user><password>test123</password><max>50</max>
</data-source>

3、添加依赖包

因为我用的是达梦数据库,james里面没有这个数据库的依赖包,所以需要额外添加,如果是mysql、oracle常用的数据库就不需要再额外添加,因为james已经支持。

找到james-2.3.2\lib,然后把需要的依赖包放进去

4、创建用户表

正常情况下会自动创建,sql语句在james-2.3.2\apps\james\conf\sqlResources.xml

如果不会自动创建,那么自己把sql语句复制出来执行

CREATE TABLE "MAIL_USERS"
("USERNAME" VARCHAR2(64) NOT NULL,"PWDHASH" VARCHAR2(50),"PWDALGORITHM" VARCHAR2(20),"USEFORWARDING" NUMBER(1,0),"FORWARDDESTINATION" VARCHAR2(255),"USEALIAS" NUMBER(1,0),"ALIAS" VARCHAR2(255),PRIMARY KEY("USERNAME")
);COMMENT ON TABLE "MAIL_USERS" IS 'James邮件用户';
COMMENT ON COLUMN "MAIL_USERS"."PWDALGORITHM" IS '加密方式,默认SHA';
COMMENT ON COLUMN "MAIL_USERS"."PWDHASH" IS '加密后的密码';
COMMENT ON COLUMN "MAIL_USERS"."USERNAME" IS '邮箱帐号';

 2.James密码是如何加密验证的

        当你通过telnet添加新用户时,比如add user test 123456,你可以查看数据库中的记录,username字段是test,pwdhash是加密后的密码,pwdalgorithm字段是“SHA”,显然用的是SHA加密方式。

        让我们看下james源码是如何实现的,网上找到apache-james-2.3.2-src.zip源码文件,版本根据自己的来,然后用idea打开。

        我们找到org.apache.james.userrepository.DefaultUser类

        第一个方法verifyPassword()是用来做密码认证,传入的参数是明文密码,通过DigestUtil.digestString()方法,转换成密文密码,然后与数据库中密码作比较,返回比较结果。请注意这里的DigestUtil.digestString()方法,在后面还在提到。

        第二个方法setPassword()是用于密码转换的,把明文转成密文,用的同样是DigestUtil.digestString()方法。

        让我们再看下 org.apache.james.security.DigestUtil类,我们可以看到digestString加密的方法。

        如果需要在自己的项目里去添加或修改用户的信息,这时候密码处理的逻辑肯定需要跟james一致,这时候我们把这个加密的方法拷贝用就行了 。

        创建个DigestUtil类,然后调用DigestUtil.digestString()来获得加密后的密码。

package com.mail;import javax.mail.MessagingException;
import javax.mail.internet.MimeUtility;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class DigestUtil {public static String digestString(String pass, String algorithm )throws NoSuchAlgorithmException  {MessageDigest md;ByteArrayOutputStream bos;try {md = MessageDigest.getInstance(algorithm);byte[] digest = md.digest(pass.getBytes("iso-8859-1"));bos = new ByteArrayOutputStream();OutputStream encodedStream = MimeUtility.encode(bos, "base64");encodedStream.write(digest);return bos.toString("iso-8859-1");} catch (IOException ioe) {throw new RuntimeException("Fatal error: " + ioe);} catch (MessagingException me) {throw new RuntimeException("Fatal error: " + me);}}private DigestUtil() {}
}

        加密支持的算法有MD5、SHA、SHA-256等 ,如果你想知道支持哪些算法,可以通过下面的代码列出所有支持的算法:

import java.security.Security;
import java.security.Provider;
import java.security.Provider.Service;public class ListAlgorithms {public static void main(String[] args) {for(Provider provider: Security.getProviders()) {for(Service service: provider.getServices()) {if ("MessageDigest".equals(service.getType())) {System.out.println(service.getAlgorithm());}}}}
}

3.总结

        集成java mail直接用明文帐号密码连接就行了,因为james会自己去加密验证,其他软件通过pop3配置,密码也是用明文就行了。

        如果觉得这种连接方式不安全有两种解决方案:

  1. 修改james源码,比较麻烦。
  2. 密码在web端加密,传输到自己后台再解密,然后用解密后的密码连接james。
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;public class SendEmail {public static void main(String[] args) {String host = "smtp.example.com"; // SMTP服务器地址String username = "your-username"; // 用户名String password = "your-password"; // 密码Properties props = new Properties();props.put("mail.smtp.host", host);props.put("mail.smtp.auth", "true");Session session = Session.getInstance(props, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(username, password);}});try {Message message = new MimeMessage(session);message.setFrom(new InternetAddress("from@example.com"));message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to@example.com"));message.setSubject("Email Subject");message.setText("Email Body");Transport.send(message);System.out.println("Email sent successfully");} catch (MessagingException e) {throw new RuntimeException("Error sending email", e);}}
}

 

这篇关于Apache James数据库存储用户信息的密码加密问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836322

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如