1.前言

最近系统被国内行业某龙头企业采用准备本地化部署,但是在操作Redis方面代码里面一直有个隐患,可能过不了该企业的网络安全扫描,所以花了半天的时间对该问题进行了深究。

一直以来我们只是对Redis的使用端口做了控制,局域网内免密码操作的Redis,但是免密操作总是存在风险,但是如何使用ServiceStack.Redis通过密码连接Redis?

2.正题

ServiceStack.Redis在4.0之后需要商用授权,而我们又使用的是很久的版本2.2,这个版本的ServiceStack.Redis在进行new RedisClient时候并没有提供可以传入密码参数的方法。

C#使用ServiceStack.Redis通过密码连接Redis_c#

很是费解,无奈开始对源码进行分析,我这里使用了ILSpy.exe工具将ServiceStack操作Redis的几个dll都添加了进去开始分析,找到我们在初始化Redis操作的RedisClient类

C#使用ServiceStack.Redis通过密码连接Redis_redis_02

我们使用的是这个方法进行实例化RedisClient的

public RedisClient(string host, int port)
: base(host, port)
{
Init();
}

随后找到了RedisNativeClient类,RedisClient的父类

C#使用ServiceStack.Redis通过密码连接Redis_赋值_03

一顿源码阅读后,找到了如何连接Redis的方法

C#使用ServiceStack.Redis通过密码连接Redis_redis_04

这里有行代码:

if (Password != null)
{
SendExpectSuccess(Commands.Auth, Password.ToUtf8Bytes());
}

如果密码不为null的时候会通过密码进行鉴权,而Password又是RedisNativeClient类的公共属性,所以我们只需要在实例化Redis后给RedisNativeClient的Password属性进行赋值即可

C#使用ServiceStack.Redis通过密码连接Redis_初始化_05

所以,我在实例化Redis后对是否需要登录密码赋值进行了判断,如果实例化的时候传入了非空的密码,我认为前端调用的时候需要密码进行鉴权,这个时候就把传入的密码对RedisNativeClient的Password进行赋值

C#使用ServiceStack.Redis通过密码连接Redis_实例化_06

最后完成了使用旧版本的ServiceStack.Redis,也可以进行密码操作。

3.总结

分析了一圈其实就两行代码:

//判断密码是否为空
if (!string.IsNullOrEmpty(token.FRedisPsd) && Redis.Password == null)
{
//不为空,赋值
Redis.Password = token.FRedisPsd;
}