很久沒寫文章了,忽然間也不知道寫什麼好了同樣,好多人可能覺得我死了,寫個文章分享一下、證實一下本身還在,很好的活着吧,刷個存在感。java
放棄了不少娛樂、休閒、旅遊、寫文章、看書、陪伴家人,靜心默默的用了接近2年多的時間突破了本身在.NET領域的最重大的軟件項目建設記錄。全程經歷了公司的核心業務系統從無到有,幾十套系統被有序的建設起來投入生產、上百人的研發隊伍建設起來、影響全國幾十萬人平常辦公的龐大的核心信息系統建設完畢、順利進入維護完善階段了。web
不少人說.NET的各類好與壞。其實實實在在的開發幾套大型系統,多用一些.NET技術了,開發效率高、簡單好用、用實際證實一下.NET並不差、只是看是誰開發出來的。每行代碼都精益求精的編寫的性能卓越、功能穩定、大型系統也能夠用.NET實現的(固然不是100%,沒有絕對、能作到相對就能夠了、畢竟有些後臺處理java也有優點、短短1-2年招聘上百個.NET熟練精通的開發人員也不容易,有時候只能是2個開發語言的都招聘、分工配合、優點互補)。redis
最近遇到一個黑客、能把公司無線網絡給劫持了、路由日誌都能獲取到了、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的朋友圈愈來愈大吧。
寫代碼的大多 都是男人、看文章累了、休息一下眼睛,夏天了看看妹子吧,而後鼓足精神好好工做吧。