C#.NET 大型企業信息化系統 - 防黑客攻擊 - SSO系統加固優化經驗分享


   好久沒寫文章了,突然間也不知道寫什么好了一樣,好多人可能以為我死了,寫個文章分享一下、證明一下自己還在,很好的活着吧,刷個存在感。

   放棄了很多娛樂、休閑、旅游、寫文章、看書、陪伴家人,靜心默默的用了接近2年多的時間突破了自己在.NET領域的最重大的軟件項目建設記錄。全程經歷了公司的核心業務系統從無到有,幾十套系統被有序的建設起來投入生產、上百人的研發隊伍建設起來、影響全國幾十萬人日常辦公的龐大的核心信息系統建設完畢、順利進入維護完善階段了。

   很多人說.NET的各種好與壞。其實實實在在的開發幾套大型系統,多用一些.NET技術了,開發效率高、簡單好用、用實際證明一下.NET並不差、只是看是誰開發出來的。每行代碼都精益求精的編寫的性能卓越、功能穩定、大型系統也可以用.NET實現的(當然不是100%,沒有絕對、能做到相對就可以了、畢竟有些后台處理java也有優勢、短短1-2年招聘上百個.NET熟練精通的開發人員也不容易,有時候只能是2個開發語言的都招聘、分工配合、優勢互補)。

 

  最近遇到一個黑客、能把公司無線網絡給劫持了、路由日志都能獲取到了、SSL通訊也能劫持,而且還獲取了單點登錄的url,其實每個公司的網絡管理員也可以得到這些核心機密信息,如何加強安全性、防止嚴重的信息泄露?

  1:需要把單點登錄的機制修改一下,不在url里傳遞OpenId、這個是后台系統獲取用戶信息的核心參數。

  2:授權碼,url,只能消費一次,就是截獲了url,第2次也無法使用、無法通過鏈接進入系統、知道了單點登錄的url也沒大用。

  3:由於公司有幾十套系統、幾十萬用戶,這么多數據如何存儲?如何保證系統的性能?高效?而且需要最少的服務器資源?畢竟也需要進行成本控制。

   Redis 可以設置一個key值的過期時間,例如5分鍾不用就自動過期,不需要額外進行處理了。一個授權碼發出去后,其實就是馬上就會消費掉、考慮到系統卡、系統異常、系統復雜的情況,寬容一些,設置為5分鍾不用就自動過期了,其實也可以設置為2-3分鍾也問題不是很大,正常情況下一般是1-5秒內就消費掉了才正常。

   Redis 的訪問效率高、因為幾十萬人在用的系統,高峰期並發量非常大、平時可以達到1萬多人實時在線、需要能有高效的讀取效率、飛快的處理速度。

   現有的底層的代碼由於結構還是很完好、思路嚴謹,在這個基礎上主要加了2個方法,一個是生成 AuthorizationCode 的方法,一個是消費 AuthorizationCode 的方法,然后提供一些對外的調用接口,當然為了提高安全性、還需要有簽名驗證碼,防止數據中途被截取篡改。

   雖然有很少精力旺盛、無聊的人會干這樣的事情、或者根本沒遇見過這個樣的人、但是只要遇到了,被破壞了,人家就說你系統不行、不安全、不穩健,太弱智、太低檔次、架構不合理、能力不行、很差勁、沒入門、門外漢、蠻干、糟爛系統。

 1         /// <summary>
 2         /// 獲取登錄操作的驗證碼
 3         /// code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。 
 4         /// </summary>
 5         /// <param name="userInfo">用戶信息</param>
 6         /// <returns>操作碼</returns>
 7         public static BaseResult GetAuthorizationCode(BaseUserInfo userInfo)
 8         {
 9             BaseResult result = new BaseResult();
10             
11             if (ServiceUtil.VerifySignature(userInfo))
12             {
13                 // 產生一個授權碼
14                 string authorizationCode = Guid.NewGuid().ToString("N");
15                 // 設置緩存服務器,消費一次,5分鍾過期。
16                 using (var redisClient = PooledRedisHelper.GetTokenClient())
17                 {
18                     // 2016-03-03 吉日嘎拉 讓緩存早點兒失效
19                     DateTime expiresAt = DateTime.Now.AddMinutes(5);
20                     string key = "code:" + authorizationCode;
21                     redisClient.Set(key, userInfo.OpenId, expiresAt);
22                 }
23                 result.ResultValue = authorizationCode;
24                 result.Status = true;
25                 result.StatusCode = Status.OK.ToString();
26                 result.StatusMessage = Status.OK.ToDescription();
27                 result.CreateSignature(userInfo);
28             }
29 
30             return result;
31         }

 

 1         /// <summary>
 2         /// 驗證授權碼
 3         /// 用掉一次后,一定要消費掉,確保只能用一次。
 4         /// </summary>
 5         /// <param name="userInfo">當前用戶信息</param>
 6         /// <param name="code">授權碼</param>
 7         /// <param name="openId">用戶唯一識別碼</param>
 8         /// <returns>驗證成功</returns>
 9         public static bool VerifyAuthorizationCode(BaseUserInfo userInfo, string code, out string openId)
10         {
11             bool result = false;
12             openId = string.Empty;
13 
14             if (userInfo != null && !ServiceUtil.VerifySignature(userInfo))
15             {
16                 return result;
17             }
18 
19             using (var redisClient = PooledRedisHelper.GetTokenClient())
20             {
21                 // 2016-03-03 吉日嘎拉 讓緩存早點兒失效
22                 string key = "code:" + code;
23                 openId = redisClient.Get<string>(key);
24                 if (!string.IsNullOrEmpty(openId))
25                 {
26                     result = true;
27                     if (userInfo != null && !string.IsNullOrEmpty(userInfo.OpenId))
28                     {
29                         result = userInfo.OpenId.Equals(openId);
30                     }
31                 }
32                 redisClient.Remove(key);
33             }
34 
35             return result;
36         }

   以前版本的OpenId,也是有過期時間,但是把過期時間定為為16個小時了,黑客拿到OpenId后,在16個小時內什么事情都干出來了,而且可能還會進入其他系統里去了,安全性不高。然后把思路調整了一下,OpenId只在內部系統之間通訊用,外部通訊用 AuthorizationCode [Code],5分鍾就過期,而且還只能用一次。只能進入一個子系統,無法進入全部子系統。雖然在理論上也存在被黑客劫持的概率、但是這個安全性比16個小時、能消費無數此次的還是安全很多很多、而且還能進入所有的系統的安全性比較下來,毛估估至少提高幾十倍的安全性是有,從時間維度、可侵入的子系統范圍上。

   其實這個功能2年前就想修改、一直精力不夠或者沒足夠重視安全性、年紀大了精力也有些不夠了,畢竟整整38歲了,一直還在一線打拼寫寫核心代碼。完成一些核心功能。

   這次高度重視這個問題后,2天就代碼寫好了(功勞是前幾天都睡足了),其實核心代碼就是文章中的這幾行代碼。自己的系統被黑客攻克了或找出問題了,就得抓緊修改啊,不能有任何借口、馬上、立刻、現在就修改過來

當系統沒幾個人用時,單點登錄怎么實現都可以、當系統每天有幾十萬人用時、就需要考慮:

1:需要多少的硬件設備?

2:需要消耗多少網絡帶寬?

3:需要多少存儲設備?

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

5:維護部署是否容易?

6:排查問題是否效率高?

7:子系統改造、銜接、難易程度如何?

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

9:如何無縫的平穩過渡?

   千萬不能有投機心理、僥幸心理,踏踏實實把每個問題都處理好,優化好

   sso系統由於都是web的,無法post方式彈出一個網頁、若能用post提交參數就安全多了、還可以加密、還可以傳遞很多參數,web的系統彈出頁面都得是get方式的,歡迎在這方面有好思路的朋友門多溝通交流,本文章技術水平可能不夠高深、本着分享的心態,寫出來,歡迎大家留言,點評、Open的心態會讓人提高很快、可以得到全行業人員的改進反饋。

   開心生活每一天,再堅持2年寫代碼,我就寫代碼到40歲了,每天提高一點點、每天多認識幾個好朋友、人生路會越來越寬、希望.NET的朋友圈越來越大吧。 

   寫代碼的大多 都是男人、看文章累了、休息一下眼睛,夏天了看看妹子吧,然后鼓足精神好好工作吧。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM