如何配置SmbSessionFactory避免构建Samba连接URL时编码问号?
解决Spring Boot SmbSessionFactory密码含问号被编码的问题
核心原因
Spring的SmbSessionFactory默认使用UriComponentsBuilder.fromPath构建SMB连接URL时,会将密码中的问号(?)编码为%3F,但SMB协议允许密码包含问号且无需编码,导致连接逻辑出错。
解决方案:自定义SmbSessionFactory子类重写URI构建逻辑
通过继承SmbSessionFactory,手动构建SMB URI,跳过默认的URL编码逻辑,直接保留密码中的原始字符:
@Bean public SmbSessionFactory smbSessionFactory() { return new SmbSessionFactory() { @Override protected URI getSmbUri() { // 手动拼接SMB连接URL,直接使用未编码的原始密码 String smbUrl = String.format("smb://%s:%s@%s:%d/%s", getDomain() + "\\" + getUsername(), getPassword(), // 保留密码中的问号等特殊字符 getHost(), getPort(), getShareAndDir()); return URI.create(smbUrl); } }; }
补充说明
- 该方法直接绕过
UriComponentsBuilder的自动编码逻辑,确保密码中的问号原样传递给SMB服务端。 - 若密码包含
@、/等可能破坏URL格式的特殊字符,可根据SMB协议要求单独转义,但多数场景下无需额外处理。
备选方案:直接使用JCIFS原生API
若不想依赖Spring的SmbSessionFactory封装,可直接使用JCIFS原生API创建连接,完全控制URL构建逻辑:
@Bean public SmbFile smbFile() throws MalformedURLException { // 构建NTLM认证对象,直接传入带问号的密码 NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("myDomain", "myUser", "myPassword?"); // 手动构建SMB连接地址 SmbFile smbFile = new SmbFile("smb://myHost:445/myShareAndDir", auth); // 设置SMB版本范围 smbFile.setDialect(DialectVersion.SMB210, DialectVersion.SMB311); return smbFile; }
内容的提问来源于stack exchange,提问作者joca1128
相关产品推荐
相关产品推荐

