您的位置:首页 > 编程语言 > C#

C#.NET 大型企业信息化系统 - 防黑客攻击 - SSO系统加固优化经验分享

2016-05-18 17:43 841 查看
好久没写文章了,也不知道写什么好,好多人可能以为我死了,写个文章分享一下证明一下自己还在很好的活着吧。



最近遇到一个黑客、能把公司无线网络给劫持了、路由日志都获取到了,而且还获取到了单点登录的url,其实公司的网络管理员也可以得到这些信息,如何加强?

1:需要把单点登录的机制修改一下,不在url里传递OpenId。

2:授权码,url,只能消费一次,就是截获了url,第2次也无法使用。

3:由于公司有几十套系统、几十万用户,这么多数据如何存储?如何保证系统的性能?高效?



Redis 可以设置一个key值的过期时间,例如5分钟不用就自动过期,不需要额外进行处理了。

Redis 的访问效率高、因为几十万人在用的系统,高峰期并发量非常大、需要能有高效的读取效率、处理速度。

现有的底层的代码由于结构还是很完好的,主要加了2个方法,一个是生成 AuthorizationCode 的方法,一个是消费 AuthorizationCode 的方法,然后提供一些对外的调用接口,当然为了提高安全性、还需要有签名验证,防止被篡改。

/// <summary>
/// 获取登录操作的验证码
/// code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
/// </summary>
/// <param name="userInfo">用户信息</param>
/// <returns>操作码</returns>
public static BaseResult GetAuthorizationCode(BaseUserInfo userInfo)
{
BaseResult result = new BaseResult();

if (ServiceUtil.VerifySignature(userInfo))
{
// 产生一个授权码
string authorizationCode = Guid.NewGuid().ToString("N");
// 设置缓存服务器,消费一次,5分钟过期。
using (var redisClient = PooledRedisHelper.GetTokenClient())
{
// 2016-03-03 吉日嘎拉 让缓存早点儿失效
DateTime expiresAt = DateTime.Now.AddMinutes(5);
string key = "code:" + authorizationCode;
redisClient.Set(key, userInfo.OpenId, expiresAt);
}
result.ResultValue = authorizationCode;
result.Status = true;
result.StatusCode = Status.OK.ToString();
result.StatusMessage = Status.OK.ToDescription();
result.CreateSignature(userInfo);
}

return result;
}


/// <summary>
/// 验证授权码
/// 用掉一次后,一定要消费掉,确保只能用一次。
/// </summary>
/// <param name="userInfo">当前用户信息</param>
/// <param name="code">授权码</param>
/// <param name="openId">用户唯一识别码</param>
/// <returns>验证成功</returns>
public static bool VerifyAuthorizationCode(BaseUserInfo userInfo, string code, out string openId)
{
bool result = false;
openId = string.Empty;

if (userInfo != null && !ServiceUtil.VerifySignature(userInfo))
{
return result;
}

using (var redisClient = PooledRedisHelper.GetTokenClient())
{
// 2016-03-03 吉日嘎拉 让缓存早点儿失效
string key = "code:" + code;
openId = redisClient.Get<string>(key);
if (!string.IsNullOrEmpty(openId))
{
result = true;
if (userInfo != null && !string.IsNullOrEmpty(userInfo.OpenId))
{
result = userInfo.OpenId.Equals(openId);
}
}
redisClient.Remove(key);
}

return result;
}


以前版本的OpenId,也是有过期时间,但是把过期时间定为为16个小时了,黑客拿到OpenId后,在16个小时内什么事情都干出来了,而且可能还会进入其他系统里去了,安全性不高。然后把思路调整了一下,OpenId只在内部系统之间通讯用,外部通讯用 AuthorizationCode [Code],5分钟就过期,而且还只能用一次。只能进入一个子系统,无法进入全部子系统,虽然在理论上也存在被黑客劫持的概率、但是这个安全性比上一个16个小时、而且还能进入所有的系统的安全性比较下来,至少提高几十倍的安全性是足够有了,从时间维度、可侵入的子系统范围上来讲。

其实这个功能2年前就想修改、一直精力不够、或者没足够重视安全性、年纪大了经历也有些不够了,毕竟38岁了,一直还在一线打拼写写核心代码。完成一些核心功能。

这次高度重视这个问题后,2天就代码写好了,其实核心代码就是文章中的这几行代码。

自己的系统被黑客攻克了、或者找出问题了,就得抓紧修改啊,不能有任何借口、马上、立刻、现在就修改过来。

当系统没几个人用时,单点登录怎么实现都可以、当系统每天有几十万人用时、就需要考虑:

1: 需要多少的硬件设备?

2:需要消耗多少网络带宽?

3:需要多少存储设备?

4:算法需要的CPU计算量?

5:维护部署是否容易?

6:排查问题是否效率高?

7:子系统改造、衔接、难易程度如何?

8:安全程度如何?效率如何?

千万不能有投机心理、侥幸心理,踏踏实实把每个问题都处理好,优化好。sso系统由于都是web的,无法post方式弹出一个网页、若能用post提交参数就安全多了、还可以加密、还可以传递很多参数,web的系统弹出页面都得是get方式的,欢迎在这方面有好思路的朋友门多沟通交流,我的文章技术水平可能不够高深、但是也本着分享的心态,写出来,欢迎大家留言,点评、Open的心态会让人提高、可以得到全社会的改进、反馈。

开心生活每一天,再坚持2年写代码,我就写代码到40岁了,每天提高一点点、每天多认识几个好朋友、人生路会越来越宽、希望.NET的朋友圈越来越大吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: