1.前言
最近系统被国内行业某龙头企业采用准备本地化部署,但是在操作Redis方面代码里面一直有个隐患,可能过不了该企业的网络安全扫描,所以花了半天的时间对该问题进行了深究。
一直以来我们只是对Redis的使用端口做了控制,局域网内免密码操作的Redis,但是免密操作总是存在风险,但是如何使用ServiceStack.Redis通过密码连接Redis?
2.正题
ServiceStack.Redis在4.0之后需要商用授权,而我们又使用的是很久的版本2.2,这个版本的ServiceStack.Redis在进行new RedisClient时候并没有提供可以传入密码参数的方法。
很是费解,无奈开始对源码进行分析,我这里使用了ILSpy.exe工具将ServiceStack操作Redis的几个dll都添加了进去开始分析,找到我们在初始化Redis操作的RedisClient类
我们使用的是这个方法进行实例化RedisClient的
public RedisClient(string host, int port)
: base(host, port)
{
Init();
}
随后找到了RedisNativeClient类,RedisClient的父类
一顿源码阅读后,找到了如何连接Redis的方法
这里有行代码:
if (Password != null)
{
SendExpectSuccess(Commands.Auth, Password.ToUtf8Bytes());
}
如果密码不为null的时候会通过密码进行鉴权,而Password又是RedisNativeClient类的公共属性,所以我们只需要在实例化Redis后给RedisNativeClient的Password属性进行赋值即可
所以,我在实例化Redis后对是否需要登录密码赋值进行了判断,如果实例化的时候传入了非空的密码,我认为前端调用的时候需要密码进行鉴权,这个时候就把传入的密码对RedisNativeClient的Password进行赋值
最后完成了使用旧版本的ServiceStack.Redis,也可以进行密码操作。
3.总结
分析了一圈其实就两行代码:
//判断密码是否为空
if (!string.IsNullOrEmpty(token.FRedisPsd) && Redis.Password == null)
{
//不为空,赋值
Redis.Password = token.FRedisPsd;
}