½éÉÜ
×÷Ϊһ¸öÔÚX94µÄº½¿Õ¹¤³Ìʦ£¬ÄãµÄÀϰåÒªÇóÄã´Ó2ºÅÂ¥µÄ¹¤³ÌͼÖмìË÷³öÒ»¸öÌØ¶¨µÄרÀû¡£²»ÐÒµÄÊÇ£¬½øÈë´óÂ¥ÐèÒªÄã³öʾÄã¾ßÓнøÈë´óÂ¥µÄ×ʸñµÄÖ¤Ã÷£¬È»ºóÄãѸËÙµØÒÔ»ÕÕµÄÐÎʽ³öʾ¸øÁ˱£°²¡£µ½ÁËÊ®ÈýÂ¥£¬½øÈ뽨Öþʦ¹¤³Ìʦͼֽ¿âÒªÇóͨ¹ýËûÃǵÄÉúÎï¼ø¶¨ÏµÍ³À´ÑéÖ¤ÄãÊÇÄãÉù³ÆµÄÄǸöÈË¡£×îºóÔÚÄãµÄÄ¿µÄµØ£¬ÄãÌṩ¸ø¿â¹ÜÀíÔ±Ò»´®¶ÔÄãºÁÎÞÒâÒåµÄ×ÖĸÊý×Ö´úÂ룬µ«ÊÇÔÚºÏÊʵÄÈËÊÖÉÏ£¬Ëü¿ÉÒÔת»»³ÉÄÄÀï¿ÉÒÔÕÒµÄÄãÐèÒªµÄ¹¤³ÌͼµÄÕæÊµË÷Òý¡£
ÔÚÉÏÃæµÄ±ÈÓ÷ÖУ¬ÎÒÃÇ¿ÉÒÔºÜÈÝÒ×µØÈ·¶¨Êʵ±µÄ°²È«´ëÊ©À´±£»¤Ãô¸ÐÊý¾ÝµÄ·ÃÎÊ¡£³ýÁ˸öÈË·ÃÎÊËùÐèÑéÖ¤£¬Ò»¸ö¸½¼ÓµÄ¿ÉÄܲ»ÊǺÜÃ÷ÏԵݲȫ´ëÊ©¾ÍÊÇÒÔ×ÖĸÊý×ÖÂëµÄÐÎʽ»ìÏý¼¼ÊõÎĵµÉí·Ý£¬²¢¼ä½ÓÓ³Éäµ½ÕæÊµµÄÎĵµÉí·ÝºÍ¿âÖеÄλÖá£

ÐÎÏóµØËµ£¬Õâ¸ö±ÈÓ÷ÊÇÒ»Á÷Ðеı»³ÆÎª¡°·Ç°²È«µÄÖ±½Ó¶ÔÏóÒýÓá±µÄWebÓ¦Óð²È«Â©¶´µÄ½â´ð£¬¸Ã©¶´ÔÚOWASP×î¹Ø¼ü©¶´Top10ÖÐÅŵÚËÄ¡£µ«Èç¹ûÕâ¾ÍÊǴ𰸵ϰ, Äã½ÓÏÂÀ´×ÔÈ»»áÎÊ¡°¹ØÓÚÎÒWebÓ¦ÓõľßÌåÎÊÌâÊÇʲôÇÒ¸ÃÈçºÎÈ¥½â¾ö?¡±
²»°²È«µÄÖ±½Ó¶ÔÏóÒýÓÃ
ÎÒÃǶÔÔÚÎÒÃÇÍøÕ¾ÉÏչʾÉÌÆ·µÄÏë·¨¶¼ºÜÊìϤ¡£Óû§Í¨¹ý·¢ÆðÇëÇóÀ´²é¿´ÉÌÆ·ÏêÇ飬ÏòËûÃǵĹºÎï³µÀïÌí¼ÓÉÌÆ·£¬»ò½øÐÐÀàËÆµÄ»î¶¯¡£ÄãºÜÓпÉÄÜ»áÀûÓÃÉÌÆ·µÄIDÈ¥±êʶÓû§ÕýÔÚÇëÇóÄļþÉÌÆ·µÄÏêϸÐÅÏ¢£¬±êʶÌí¼Ó½øËûÃǹºÎï³µµÄÉÌÆ·µÈµÈ¡£×îÖØÒªµÄÊÇ£¬Õâ¸öIDºÜÓпÉÄÜÊÇ´æ´¢ÉÌÆ·ÐÅÏ¢µÄÊý¾Ý¿â±íµÄÖ÷¼ü¡£Èç¹ûÕæÊÇÕâÑù£¬ÄÇôÎÒÃǾÍÓµÓÐÁËÒ»¸öÖ±½Ó¶ÔÏóÒýÓá£ÔÚÍøÒ³ÉÏչʾµÄij¸öÉÌÆ·£¨¶ÔÏ󣩱»Ìض¨µÄID±êʶ£¬¶øÕâ¸öIDÊǶÔÊý¾Ý¿âÖÐÏàͬ±êʶµÄÖ±½ÓÒýÓá£
¡°ËµµÄ²»´í£¬µ«ÄÇÓÖÈçºÎ£¿¡±ÊÇÕâÑù£¬ÔÚ¼òµ¥µÄÉ̼ҶԹ˿ͳ¡¾°Ï£¬ÉÏÎÄËù½²µÄÇé¿ö²»ÊÇʲôÎÊÌâ¡£µ«¼Ù¶¨ÕâÊÇÒ»¸ö½ðÈÚÀà·þÎñÓ¦Ó㬱ȷ½ËµÊÇÄã×î³£ÓõÄÍøÉÏÒøÐУ¬ÉÏÃæÓÐÄãµÄ¸÷¸ö»îÆÚ¡¢¶¨ÆÚ´¢ÐîÕË»§ºÍÆäËûÃô¸ÐÊý¾Ý£¬Äǽ«»áÔõÑùÄØ£¿ÏëÏóһϣ¬ÄãÔÚÄãµÄÕË»§Ò³ÃæÑ¡Ôñ²é¿´ ID Ϊ 1344573490 µÄ´æ¿îÕË»§µÄÏêϸÐÅÏ¢£º

×÷Ϊһ¸ö¾¹ýÉí·ÝºËʵµÄÃûΪMary WigginsµÄÓû§£¬ÍøÕ¾ÏÔʾÁËÕë¶ÔÄã´æ¿îÕË»§µÄÐÅÏ¢£º

ÎÒÃÇ¿ÉÒÔÖ±½Ó¿´³öÕâ¸ö֧Ʊ»§Í·¾ÍÊÇÎÒÃÇÓµÓеÄÕË»§£¬Í¬Ê±Ò²ÄÜÈ·ÈÏÕâÊÇÒ»¸öÖ±½ÓÒýÓᣵ«ÒªÊÇÄã¾ö¶¨°Ñ accountNumber ²ÎÊý´Ó 1344573490 ¸ÄΪ 1344573491£¬Äǽ«»á·¢ÉúÊ²Ã´ÄØ£¿

Erin Maley£¬ËÊÇErin Maley£¿ÄDz»ÊÇÎÒÃÇ¡£ÎÒÃÇ×÷ΪMary WigginsÊÇÒѾÃ÷È·±»ÈÏÖ¤¹ýµÄ¡£ÎÒÃÇËùÓÐËù×öµÄÊÂÇé¾ÍÊÇ˳ÐòµØÔö¼ÓÕË»§ºÅÖ±µ½ÏÂÒ»¸ö¿ÉÄܵÄÖµ£¬²¢ÇÒÎÒÃÇ¿ÉÒÔ¿´µ½Ò»¸ö²»ÊÇÎÒÃÇËù³ÖÓеÄÕË»§ÐÅÏ¢¡£ÔÚÕâ¸öÀý×ÓÖУ¬ÎÒÃÇÓÐÒ»¸öÖ±½Ó¹ØÁªµÄÕË»§£¬Ëü¿ÉÒÔ±»¶¨ÒåΪϵͳÄÚÈκεط½±»±êʶµÄÕË»§ºÅ¡£¸ü½øÒ»²½Ëµ£¬ÎÒÃÇÑÝϰÁËÒ»¸öDZÔÚµÄÎÊÌâ£¬ÆØ¹âÒ»¸öÖ±½ÓÏà¹ØµÄÕË»§ÊǼòµ¥µÄÊý¾Ý¹¤³Ì¡£
Èç¹ûÄã×Ô¼º¾õµÃÕâ²»ÊÇÖ±½ÓÒýÓÃÈǵĻö£¬¶øÊÇÉí·ÝÑéÖ¤ÉϳöÁ˲î´í£¬ÄÇôÄãÖ»¶ÔÁËÒ»°ë¡£ÎÒÃÇÌÖÂÛ²»°²È«Ö±½Ó¶ÔÏóÒýÓÃËùÔì³ÉµÄȱÏÝʱ£¬Êµ¼ÊÉÏ¿´µ½ÁËÁ½¸öÎÊÌâ¡£ÎÒ·¢ÏÖÏÂͼÄܹ»¸üÇå³þµÄÃèÊöÕâ¸öȱÏݾ¿¾¹ÊÇʲô£º

Èç¹û²»°²È«µÄÖ±½Ó¶ÔÏóÒýÓÃÉæ¼°ÒÔÏÂÁ½·½Ãæ¡¡
й¶Ãô¸ÐÊý¾Ý
ȱ·¦ºÏÀíµÄ·ÃÎÊ¿ØÖÆ
¡¡ÄÇôÎÒÃǶÔÓÚÃÖ²¹Õâ¸öȱÏݵĿ´·¨ÊÇʲô£¬ÒÔ¼°ÎÒÃÇÓ¦¸ÃºÎʱ²ÉÈ¡Ðж¯£¿½ÓÏÂÀ´£¬ÎÒÃÇÊ×ÏȽâ¾öÓ°Ïì×î´ó·¶Î§×î¹ãµÄÎÊÌ⡪¡ªºÏÀíµÄ·ÃÎÊ¿ØÖÆ¡£
¶à²ã¼¶µÄ·ÃÎÊ¿ØÖÆ
¾ÍÏñÎÄÕ¿ªÍ·¾ÙµÄÀý×Ó£¬¶à²ã¼¶µÄ·ÃÎÊ¿ØÖÆÊDZØÐëµÄ¡£ËäÈ»ÎÒÃÇÓÐȨ½øÈë´óÂ¥£¬µ«½øÈëÂ¥ÄÚÄ³Ð©ÇøÓòÐèÒªÌØ¶¨µÄȨÏÞ¡£µ±ÎÒÃÇ¿¼ÂÇÔÚWebÓ¦ÓÃÖб£»¤×ÊԴʱ£¬¿ÉÒÔʹÓÃÕâÑùµÄ×¼ÔòÀ´´ïµ½Ä¿µÄ¡£
ͨ¹ý·ÓɽøÐзÃÎÊ¿ØÖÆ
Ê×ÏÈ£¬µ±Ç°ºÏ·¨Óû§ÊÇ·ñÓÐȨÇëÇó×ÊÔ´£¿ÔÚÎÒÃǶԸÃÓû§Ò»ÎÞËùÖªµÄÇé¿öÏ£¬¸ÃÈçºÎÈ·¶¨µ±Ç°Óû§¿ÉÒÔ±»ÔÊÐí·¢ÆðÕâ¸öÇëÇó£¿Òò´ËµÚÒ»²½ÎÒÃÇÒª×öµÄÊÇ£¬ÔÚºÍÓû§½»»¥Ê±£¬Í¨¹ýÌí¼Ó·ÃÎÊ¿ØÖÆÀ´±£»¤×ÊÔ´¡£
ÔÚASP.NETÖУ¬Óû§½»»¥Í¨¹ý¿ØÖÆÆ÷¶¯×÷£¨controller action£©Íê³É¡£ÎÒÃÇ¿ÉÒÔÔÚASP.NET MVC¿ØÖÆÆ÷ÉÏʹÓÃ[Authorize]ÌØÐÔ£¨attribute£©À´È·±£Óû§Ö»ÓÐÏȾ¹ýϵͳºËʵÉí·Ý²ÅÄÜÖ´ÐпØÖÆÆ÷Éϵ͝×÷£¬¶øÄäÃûÓû§½«±»¾Ü¾ø¡£
[Authorize] public class AccountsController : Controller { [HttpGet] public ActionResult Details(long accountNumber) { //... |
ÕâÑù¾ÍÈ·±£ÁËAPIÎÞ·¨±»¹«¿ªÊ¹Ó㬸ù¾ÝÄãµÄASP.NETÅäÖã¬Óû§»á±»Öض¨Ïòµ½µÇÂ¼Ò³Ãæ£¨Ä¬ÈÏÐÐΪ£©¡£[Authorize]ÌØÐÔͨ¹ý¶îÍâµÄÔ¼ÊøÀ´Æ¥ÅäÌØ¶¨µÄÓû§ºÍ½ÇÉ«£º
[Authorize(Roles = "Admin, Manager")] public class AccountsController : Controller { //.. |
[Authorize]ÌØÐÔ³ýÁË¿ÉÒÔ±»Ó¦Óõ½¿ØÖÆÆ÷¶¯×÷ÉÏÍ⣬»¹ÄܽøÐиü¶àÁ£¶ÈµÄ¿ØÖÆ¡£ÀýÈçÔÚ¿ØÖÆÆ÷ÉÏ·ÅÖÃÉí·ÝÑéÖ¤Ô¼Êø£¬Í¬Ê±ÔÚ¿ØÖÆÆ÷µÄ²»Í¬¶¯×÷ÉÏʹÓûùÓÚ½ÇÉ«µÄ·ÃÎÊ¿ØÖÆ¡£
ÔÚÎÒÃǵÄÒøÐÐÕË»§Àý×ÓÖУ¬Ö»¶ÔÓû§½øÐÐÉí·ÝÑéÖ¤ÊDz»¹»µÄ£¬ÒòΪÎÒÃÇ£¨Ö»¾¹ýÉí·ÝÑéÖ¤µÄÓû§£©¾¹È»ÄÜ·ÃÎÊÁíÒ»¸öÓû§µÄ֧ƱÕË»§ÐÅÏ¢¡£¶ÔÓÚÏñÒøÐÐÕË»§Àý×ÓÖп´µ½µÄÕâÖÖÀÄÓÃÐÐΪ£¬Í¨³£±»³Æ×÷ΪºáÏòȨÏÞÌáÉý£¬Óû§¿ÉÒÔ·ÃÎÊÆäËûÏàͬµÈ¼¶µÄÓû§ÐÅÏ¢¡£È»¶ø£¬ÓÐȨ·¢Æð¶Ôij¸ö×ÊÔ´µÄÇëÇóÓëÓµÓжÔʵ¼Ê×ÊÔ´µÄȨÏÞÊÇÍêÈ«²»Í¬µÄ¸ÅÄî¡£
Êý¾Ý·ÃÎÊ¿ØÖÆ
Òò´Ë£¬ÎÒÃDZØÐë²ÉÈ¡µÄµÚ¶þ²ãÒ²ÊÇ×îÖØÒª·ÃÎÊ¿ØÖƾÍÊÇ£¬±£Ö¤Óû§±»ÊÚȨ·ÃÎÊ×ÊÔ´¡£ÔÚ»ùÓÚ½ÇÉ«µÄ·ÃÎÊ¿ØÖƵÄÇé¿öÏ£¬Õâ¾Í¸úÈ·±£Óû§ÊôÓÚºÏÀíµÄ½ÇɫһÑùÈÝÒס£Èç¹û±»ÇëÇóµÄ×ÊÔ´Ö»ÐèҪij¸öÌáÉýµÄȨÏÞ£¬Äã¿ÉÒÔÀûÓÃ֮ǰÑÝʾµÄ[Authorize]µÄRoleÊôÐÔÀ´¸ã¶¨¡£
[Authorize(Roles = "Admin")] public class AccountsController : Controller { //.. |
µ«ÊǸü¶àµÄʱºò£¬Äã±»ÒªÇóÔÚÊý¾Ý²ãÃæ¶ÔÓû§½øÐÐȨÏÞÑéÖ¤£¬ÒÔ±£Ö¤ÆäÓÐȨ·ÃÎÊËùÇëÇóµÄ×ÊÔ´¡£¿¼Âǵ½ÊÜÐí¶à²»Í¬ÒòËØµÄÓ°Ï죬½â¾ö·½°¸¶àÖÖ¶àÑù£¬¾ÍÉÏÎÄÌáµ½µÄ²é¿´ÒøÐÐÕË»§ÏêÇéµÄ°¸Àý£¬ÎÒÃÇ¿ÉÒÔÑéÖ¤Óû§ÊÇ·ñΪÆäËùÇëÇóÕË»§µÄÓµÓÐÕߣº
[Authorize] public class AccountsController : Controller { [HttpGet] public ActionResult Details(long accountNumber) { Account account = _accountRepository.Find(accountNumber); if (account.UserId != User.Identity.GetUserId()) { return new HttpUnauthorizedResult("User is not Authorized."); } //... |
¼ÇµÃÎÒÃÇÒѾÔÚ¿ØÖÆÆ÷¼¶±ðʹÓÃÁË[Authorize]ÌØÐÔ£¬ËùÒÔû±ØÒªÔÚ¶¯×÷¼¶±ð»ÉßÌí×ã¡£
ÐèÒªÖØµã×¢ÒâµÄÊÇ£¬ÔÚÉÏÃæµÄ¹ØÓÚÔÚASP.NETÖÐʹÓÃForms AuthenticationÒý·¢µÄ·ÇÊÚȨ½á¹ûµÄÀý×ÓÖн«»áÇ¿ÖÆÒ»¸ö302Ìø×ªµ½µÇÂ½Ò³Ãæ£¬ÎÞÂÛÓû§ÊÇ·ñÒѾµÄµ½ÊÚȨ¡£Òò´Ë£¬Äã»òÐíÐèÒª¶Ô´¦ÀíÕâÖÖÐÐΪ×÷³ö±ØÒªµÄ¸Ä±ä£¬ÕâÈ¡¾öÓÚÄãµÄÓ¦Óã¬ÄãµÄÐèÇóºÍÄãÓû§µÄÆÚÍû¡£ÄãµÄÑ¡Ôñ»òÕßÄãÊÇ·ñÐèÒª´¦ÀíÕâÖÖÐÐΪºÜ´ó³Ì¶ÈÉÏÒÀÀµÓÚ¿ò¼ÜµÄ·ç¸ñ£¬Ê¹ÓÃOWINÄ£¿é£¬ºÍÄãµÄÓ¦ÓõÄÐèÒª¡£
ºÃ´¦ÊǼõÉÙÁËȥȷ¶¨Ã»ÓÐÓû§ÌáȨµÄ´ÎÊý£¬±£Ö¤Á˺ÏÊʵķÃÎÊȨÏÞ¿ØÖÆ¡£ÖÁÉÙ£¬ÎÒÃÇ¿ÉÒÔ¼ÓÇ¿¶ÔÇëÇó±¾ÉíºÍÇëÇó¶Ô±»ÇëÇó×ÊÔ´µÄ·ÃÎʵķÃÎÊ¿ØÖÆ¡£µ«ÊÇ£¬ÈçͬÎÒÇ°ÃæÌáµ½µÄÈô¸ÉÖÖ³¡ºÏ£¬ ÔÚÎÒÃǵÄÓ¦ÓüÓÇ¿·ÀÖ¹Êý¾Ýй¶×ÜÊÇÓ¦¸ÃÆÀ¹ÀµÄÒ»¸ö°²È«²½Ö衣ʲôÊÇÎÒËù˵µÄ¡°Êý¾Ýй¶¡±£¿ÎÒÃÇ¿ÉÒÔͨ¹ýÑо¿ÆäËû°üº¬²»°²È«µÄÖ±½Ó¶ÔÏóÒýÓã¨Èç»ìÏý£©À´»Ø´ðÕâ¸öÎÊÌâ¡£
»ìÏý
»ìÏý ¾ÍÊǹÊÒâÒþ²ØÒâͼµÄÐÐΪ¡£ÔÚÎÒÃÇÕâ¶ù, ÎÒÃÇ¿ÉÒÔʹÓûìÏýÊÖ¶ÎÀ´Íƶϰ²È«ÐÔ¡£ Ò»¸öÈËÃÇÈÏͬµÄ¼òµ¥Àý×Ó¾ÍÊÇURL¶ÌÁ´¡£ËäÈ»³õÖÔ²¢²»ÊÇΪÁ˰²È«ÐÔ, ÏñÕâÑùµÄURL http://bit.ly/1Gg2Pnn ÊÇ´ÓÕæÊµµÄURL´Ó»ìÏý¹ýÀ´µÄ¡£ ¸ù¾ÝÕâ¸ö¶ÌÁ´, Bit.lyÄܹ»½«»ìÏýµÄURL http://bit.ly/1Gg2Pnn Ó³Éäµ½ÕæÕýµÄhttp://lockmedown.com/preventing-xss-in-asp-net-made-easy.
ÎÒʹÓÃÁ˹ØÓÚÒøÐÐÕË»§½»»¥µÄ½ðÈÚÀý×Ó£¬ÒòΪÕâÊÇÒ»¸öÍêÃÀµÄÀý×Ó£¬ÔÚÆäÖеÄÔªÊý¾ÝÊǺÜÃô¸ÐµÄ¡£ÔÚÕâÖÖÇé¿öÏ£¬Ò»¸ö֧ƱÕÊ»§¾ÍÊÇÎÒÃÇÒª±£»¤µÄÊý¾Ý¡£¶øÕË»§ºÅÂë¾ÍÊǹØÓÚ֧ƱÕ˺ŵÄÔªÊý¾Ý£¬ÎÒÃÇÈÏΪÕâÊÇÃô¸ÐÊý¾Ý¡£
ÎÒÃÇ¿´µ½ÔÚÇ°ÃæÎÒÃÇÖ»ÊÇÔö¼ÓÁËÕʺŵÄÊýÖµ¾ÍÄܹ»Ñϸñ·ÃÎÊÁíÒ»¸öÓû§µÄ֧ƱÕÊ»§£¬ÒòΪûÓÐÊý¾Ý¼¶·ÃÎÊ¿ØÖÆ¡£µ«ÎÒÃÇ¿ÉÒÔͨ¹ý»ìÏýÕ˺ލÁ¢ÁíÒ»·ÀÓùÆÁÕÏʹ¶ñÒâÓû§Ê§È¥Ö±½Ó¼ÝԦϵͳµÄÄÜÁ¦,Õâͨ¹ý¸Ä±äÊýÖµ¾ÍÐС£
¿ÉÒÔʵÏÖ²»Í¬¼¶±ðµÄ»ìÏý£¬Ã¿Ò»¼¶±ð¶¼ÄÜÌṩ²»Í¬¼¶±ðµÄ°²È«ÐÔºÍÆ½ºâÐÔ.ÎÒÃǽ«¿´µ½µÚÒ»¸öÑ¡ÏîÊÇÒ»ÖֱȽϳ£¼ûµÄ£¬°²È«µÄµ«ÓÐЩÏÞÖÆµÄÑ¡ÏÎÒϲ»¶³ÆÖ®Îª¡°ÊÓÒ°¡±£¬¸Ã´Ê¼ä½Ó²Î¿¼µØÍ¼¡£
×÷ÓÃÓò¼ä½ÓÒýÓÃÓ³Éä
ÒýÓÃÓ³ÉäÓë Bit.ly ¶ÌÍøÖ·²¢Ã»ÓÐʲô²»Í¬£¬ÄãµÄ·þÎñÆ÷ÖªµÀÔõÑù½«Ò»¸ö¹«¿ªµÄ±íÃæÖµÓ³Éäµ½Ò»¸öÄÚ²¿ÖµÀ´´ú±íÃô¸ÐÊý¾Ý¡£×÷ÓÃÓò´ú±íÎÒÃÇÓÃÓÚÏÞÖÆÓ³ÉäʹÓöø·ÅÈëµÄÏÞÖÆÌõ¼þ¡£Õâ¶ÔÀíÂÛÑо¿ÒѾ×ã¹»ÁË£¬ÎÒÃÇÀ´¿´Ò»¸öÀý×Ó£º
ÎÒÃÇÈÏΪһ¸öÕ˺űàºÅÀýÈç1344573490ÊÇÒ»¸öÃô¸ÐÊý¾Ý£¬ÎÒÃÇÏ£ÍûÒþ²ØËü²¢Ö»Ìṩ¿É±»È·ÈϵÄÕ˺ųÖÓÐÕß¡£ÎªÁ˱ÜÃⱩ¶Õ˺űàºÅ£¬ÎÒÃÇ¿ÉÒÔÌṩһ¸ö¼ä½ÓÒýÓõ½Õ˺űàºÅµÄ¹«¿ª±íÃæÖµ¡£·þÎñÆ÷½«»áÖªµÀÔõÑù°ÑÕâ¸ö¼ä½ÓÒýÓÃÓ³É仨ֱ½ÓÒýÓã¬Õâ¸öÖ±½ÓÒýÓÃÖ¸ÏòÎÒÃǵÄÕ˺űàºÅ¡£·þÎñÆ÷ʹÓõÄÓ³Éä´æ´¢ÔÚÒ»¸ö ASP.NET Óû§»Ø»°ÖУ¬Õâ¾ÍÊÇ×÷ÓÃÓò£¬¹ØÓÚ×÷ÓÃÓòµÄ¸ü¶àÄÚÈÝ£¬À´¿´¿´Õâ¸öʵÏÖ£º
public static class ScopedReferenceMap { private const int Buffer = 32;
/// <summary>
/// Extension method to retrieve a public facing indirect value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static string GetIndirectReference<T>(this T value)
{
//Get a converter to convert value to string
var converter = TypeDescriptor.GetConverter(typeof (T));
if (!converter.CanConvertTo(typeof (string)))
{
throw new ApplicationException("Can't convert value to string");
}
var directReference = converter.ConvertToString(value);
return CreateOrAddMapping(directReference);
}
/// <summary>
/// Extension method to retrieve the direct value from the user session
/// if it doesn't exists, the session has ended or this is possibly an attack
/// </summary>
/// <param name="indirectReference"></param>
/// <returns></returns>
public static string GetDirectReference(this string indirectReference)
{
var map = HttpContext.Current.Session["RefMap"];
if (map == null ) throw new ApplicationException("Can't retrieve direct reference map");
return ((Dictionary<string, string>) map)[indirectReference];
}
private static string CreateOrAddMapping(string directReference)
{
var indirectReference = GetUrlSaveValue();
var map =
(Dictionary<string, string>) HttpContext.Current.Session["RefMap"] ??
new Dictionary<string, string>();
//If we have it, return it.
if (map.ContainsKey(directReference)) return map[directReference];
map.Add(directReference, indirectReference);
map.Add(indirectReference, directReference);
HttpContext.Current.Session["RefMap"] = map;
return indirectReference;
}
private static string GetUrlSaveValue()
{
var csprng = new RNGCryptoServiceProvider();
var buffer = new Byte[Buffer];
//generate the random indirect value
csprng.GetBytes(buffer);
//base64 encode the random indirect value to a URL safe transmittable value
return HttpServerUtility.UrlTokenEncode(buffer);
}
} |
ÕâÀÎÒÃÇ´´½¨ÁËÒ»¸ö¼òµ¥µÄ¹¤¾ßÀà ScopedReferenceMap£¬¿ÉÒÔÌṩÀ©Õ¹µÄ·½·¨´¦ÀíÒ»¸öÖµÀýÈçÎÒÃǵÄÒøÐп¨ºÅ1344573490´¦Àí³É Xvqw2JEm84w1qqLN1vE5XZUdc7BFqarB0£¬Õâ¾ÍÊÇËùνµÄ¼ä½ÓÒýÓá£
×îÖÕ£¬µ±Ò»¸ö¼ä½ÓÒýÓÃÖµ±»ÇëÇóʱ£¬ÎÒÃÇʹÓÃÒ»¸öÓû§»á»°À´×÷Ϊ±£³ÖÇëÇóÖеļä½ÓÒýÓúÍÖ±½ÓÒýÓÃÖ®¼äµÄÓ³ÉäµÄÒ»ÖÖ·½·¨¡£Óû§»á»°³ÉΪ¼ä½ÓÒýÓõÄ×÷ÓÃÓò£¬¶øÇÒÇ¿ÖÆÔÚÿ¸öÓû§Ó³ÉäÉϼÓÉÏʱ¼äÏÞÖÆ¡£Ö»Óо¹ýÑéÖ¤ºÍÖ¸¶¨µÄÓû§»á»°²Å¾ßÓмìË÷µÄÄÜÁ¦¡£
Äã¿ÉÒÔÀûÓÃËüÔÚÈκÎÄãÐèÒªµÄµØ·½´´½¨¼ä½ÓÒýÓã¬ÀýÈ磺
AccountNumber = accountNumber.GetIndirectReference(); //create an indirect reference |
ÏÖÔÚ£¬ÔÚÒ»¸öʹÓÃÈçÏÂURLµÄ´«ÈëÇëÇó£¨ÇëÇóÒ»¸öÕ˺ŵÄÏêϸÐÅÏ¢£©£º

ÎÒÃÇ¿ÉÒÔ¿´³ö£¬¶ÔaccountNumberµÄ¼ä½ÓÒýÓÃÓ³Éäͨ¹ýÓëÎÒÃǵķÃÎÊ¿ØÖƺÏ×÷ÖØÐµõ½ÕæÊµÖµ£º
[HttpGet] public ActionResult Details(string accountNumber) { //get direct reference var directRefstr = accountNumber.GetDirectReference(); var accountNum = Convert.ToInt64(directRefstr);
Account account = _accountRepository.Find(accountNum);
//Verify authorization
if (account.UserId != User.Identity.GetUserId())
{
return new HttpUnauthorizedResult("User is not Authorized.");
}
//… |
ÔÚÎÒÃǶԻñµÃÖ±½ÓÒýÓõij¢ÊÔÖУ¬Èç¹ûASP.NETÓû§»á»°Ã»ÓлñµÃÒ»¸öÓ³É䣬ÄǾͿÉÄÜÊÇÊܵ½Á˹¥»÷¡£µ«ÊÇ£¬Èç¹ûÓ³Éä´æÔÚ£¬ÈÔÈ»µÃµ½ÁËÖ±½ÓÒýÓã¬Ôò¿ÉÄÜÊÇÖµ±»´Û¸ÄÁË¡£
ÕýÈçÎÒÇ°ÃæÌáµ½µÄ£¬Óû§»á»°´´½¨ÁËÒ»¸ö×÷ÓÃÓò£¬Óû§ºÍʱ¼äÔ¼ÊøÏÞÖÆÁËÓ³É仨ֱ½ÓÒýÓõÄÄÜÁ¦¡£ÕâЩÏÞÖÆÌõ¼þÒÔÆä×ÔÉíµÄÐÎʽÌṩ¶îÍâµÄ°²È«´ëÊ©¡£µ«ÊÇ£¬Äã»òÐíÔÚʹÓà ASP.NET »á»°×´Ì¬Ê±Óöµ½ÎÊÌ⣬Õâ¿ÉÄÜÊÇÓÉÓÚÒÑÖªµÄ°²È«Èõµã£¬ÄãÒ²¿ÉÄÜ»áÎÊÔõÑù²ÅÄÜÈÃÕâЩÏÞÖÆÌõ¼þÓëÌṩº¬×´Ì¬´«Ê䣨Representational State Transfer£©·ç¸ñµÄÒýÇæÀýÈ糬ýÌå״̬ӦÓÃÒýÇæÁ¼ºÃµÄºÏ×÷¹²´¦£¿ÕæÊǸöºÃÎÊÌ⣬ÈÃÎÒÃÇÀ´¼ì²éÒ»Ð©Ìæ´úÑ¡Ïî°É¡£
HATEOAS Gonna Hate
Èç¹ûÄã˼¿¼¹ýͨ¹ýÍøÂç·þÎñ½øÐеĵäÐͽ»»¥·½Ê½£¬ÕâÖÖÔÚÄãµÄÓ¦ÓÃÖÐͨ¹ý·¢ËÍÒ»¸ö request ºÍ½ÓÊÜÒ»¸ö°üº¬¶îÍⳬýÌåÁ´½Ó£¨ÀýÈç URLs)µÄ response À´»ñµÃ¶îÍâµÄ×ÊÔ´µÄ·½Ê½¶Ô web ¿ª·¢ÕßÀ´ËµÊÇÒ»¸ö¿ÉÒÔÀí½âµÄ¸ÅÄî¡£
Õâ¸ö¸ÅÄî¾¹ý¸ß¶ÈµÄ¾«Á¶ÒѾ³ÉΪ¹¹½¨ REST ·ç¸ñµÄÍøÂç·þÎñµÄÖ§ÖùÖ®Ò»£º³¬Ã½Ìå×÷ΪӦÓóÌÐò״̬»ò HATEOAS µÄÒýÇæ¡£ÓÃÒ»¾ä»°À´½âÊÍ HATEOAS ÊÇÍøÂç·þÎñÌṩ¶ÔÓÚ×ÊÔ´·¢ÏÖ²Ù×÷µÄÄÜÁ¦£ºËüͨ¹ýÔÚ HTTP ÏìÓ¦ÖÐÌṩ³¬Ã½ÌåÁ´½Ó¡£Õâ²»ÊÇһƪ¹ØÓÚ¶¨Òå REST ·ç¸ñÍøÂç·þÎñµÄÂÛÎÄ£¬ËùÒÔ£¬Èç¹û REST ºÍ HATEOAS ¶ÔÄãÀ´ËµÊÇİÉú¸ÅÄÄãÐèÒª²é¿´¹ØÓÚ REST ºÍ¹ØÓÚ HATEOAS µÄ×ÊÁÏÀ´¶ÔËûÃÇÓÐÒ»¸öÁ˽⡣
Òò´Ë£¬Ìṩ°üº¬ÓÐ×÷ÓÃÓòµÄ¼ä½ÓÒýÓòÎÊýµÄ URL µÄÏë·¨ÓëÏñ HATEOAS ÕâÑùµÄ¸ÅÄî»òÐèÒªÒ»Ö±Ìṩ³Ö¾ÃÐÔ URL (¾ßÓнϳ¤Éú´æÊ±¼äµÄ URL )Ö®¼äÊÇÓкܴóÀ§Äѵġ£Èç¹ûÎÒÃÇÏ£ÍûÌṩ³Ö¾ÃÐÔ URL µÄͬʱ£¬°üº¬¼ä½ÓÒýÓÃÖµ£¬ÄÇôÎÒÃǾÍÐèÒª²ÉÓÃÒ»ÖÖ²»Í¬µÄ°²È«·½·¨£¬ÎÒÃÇÓ¦¸ÃÔõô×öÄØ£¿
¾²Ì¬¼ä½ÓÒýÓÃÓ³Éä
ΪÁËÌṩ°üº¬¼ä½ÓÒýÓõij־ÃÐÔ URL£¬ÎÒÃǽÓÏÂÀ´¾ÍÐèҪһЩ·½·¨À´ÔÚÈÎÒâ¸ø¶¨µÄʱ¼ä»òÕßÖÁÉÙÊÇÔÚδÀ´Ï൱³¤µÄÒ»¶Îʱ¼äÄÚ½«¼ä½ÓÖµÓ³É仨ÔʼµÄÖ±½ÓÖµ¡£Èç¹ûÎÒÃÇÏëÒª³Ö¾ÃÐÔ£¬ÄÇôÏñʹÓÃÒ»¸öÓû§»á»°À´Î¬³ÖÒ»¸öÒýÓÃÓ³ÉäÕâÑùµÄÏÞÖÆÌõ¼þ½«²»ÔÙÊǸö¿ÉÓõÄÑ¡Ïî¡£ÈÃÎÒÃÇÀ´¿´¿´¿ÉÒÔʹÓþ²Ì¬¼ä½ÓÒýÓÃÓ³Éä·½°¸µÄ³¡¾°¡£
¼ÙÉèÄãÓÐÒ»¸ö B2B ÍøÂçÓ¦Óã¬ËüÔÊÐíÉ̼һñµÃÖ¸¶¨¸øËûÃÇµÄ VIP ÉÌÆ·µÄ¶¨¼Û¡£¸ø¿Í»§ÏµÍ³·¢ËÍÒ»¸öÇëÇ󣬷µ»ØÒ»¸ö°üº¬Á´½Óµ½´Ë¿Í»§µÄ VIP ÉÌÆ·µÄ¸½¼Ó³¬Ã½ÌåÁ´½ÓµÄÏìÓ¦¡£µ±µã»÷ VIP ÉÌÆ·Á´½Óʱ£¬½ÓÊÕµ½µÄÏìÓ¦¾Í°üº¬ËûÃÇÖ¸¶¨É̼ҵÄËùÓпÉÓà VIP ÉÌÆ·µÄ³¬Ã½ÌåÁ´½Ó¡£
ÔÚÎÒÃǵÄÀý×ÓÖУ¬ÎÒÃǾö¶¨Í¨¹ý´´½¨Ò»¸ö¼ä½ÓÒýÓ㬶ÔVIPÉÌÆ·URLÖеÄVIPÉÌÆ·ID¼ÓÒÔ»ìÏý£¬µ½Ê±ºòÎÒÃÇÄÜºÜ¿ìµØÖØÐÂÓ³É仨ÉÌÆ·µÄʵ¼ÊID¡£
Àý×Ó£º https://AppCore.com/business/Acme/VIP/Products/99933
Õë¶ÔÎÒÃǵĴ¦¾³£¬¼ÓÃÜÊÇÒ»¸ö²»´íµÄÑ¡Ôñ£¬ÕâʹµÃÎÒÃÇÄܸüºÃµÄÕÆ¿Ø½«¼ä½ÓÒýÓÃÓ³Éä»ØÊµ¼ÊÉÌÆ·IDµÄÉúÃüÖÜÆÚ¡£
ÈçͬÎÒÃÇÔÚÓòÒýÓÃÀý×ÓÖÐ×öµÄÄÇÑù£¬ÀûÓÃÏàͬµÄAPI£¬À´¿´¿´Ëü½«»á³ÉΪʲôÑù×Ó£¬È»ºóÎÒÃÇ´ø×ʨעºÍ¶îÍâµÄÑ¡Ôñ£¬ÔÙÌÖÂÛÒ»ÏÂÎÒÃÇ×öÁËʲôºÍΪʲôÓÃÕâÖÖ·½·¨£º
public static class StaticReferenceMap { public const int KeySize = 128; //bits public const int IvSize = 16; //bytes public const int OutputByteSize = KeySize / 8; private static readonly byte[] Key;
static StaticReferenceMap()
{
Key = //pull 128 bit key in
}
/// <summary>
/// Generates an encrypted value using symmetric encryption.
/// This is utilizing speed over strength due to the limit of security through obscurity
/// </summary>
/// <typeparam name="T">Primitive types only</typeparam>
/// <param name="value">direct value to be encrypted</param>
/// <returns>Encrypted value</returns>
public static string GetIndirectReferenceMap<T>(this T value)
{
//Get a converter to convert value to string
var converter = TypeDescriptor.GetConverter(typeof (T));
if (!converter.CanConvertTo(typeof (string)))
{
throw new ApplicationException("Can't convert value to string");
}
//Convert value direct value to string
var directReferenceStr = converter.ConvertToString(value);
//encode using UT8
var directReferenceByteArray = Encoding.UTF8.GetBytes(directReferenceStr);
//Encrypt and return URL safe Token string which is the indirect reference value
var urlSafeToken = EncryptDirectReferenceValue<T>(directReferenceByteArray);
return urlSafeToken;
}
/// <summary>
/// Give a encrypted indirect value, will decrypt the value and
/// return the direct reference value
/// </summary>
/// <param name="indirectReference">encrypted string</param>
/// <returns>direct value</returns>
public static string GetDirectReferenceMap(this string indirectReference)
{
var indirectReferenceByteArray =
HttpServerUtility.UrlTokenDecode(indirectReference);
return DecryptIndirectReferenceValue(indirectReferenceByteArray);
}
private static string EncryptDirectReferenceValue<T>(byte[] directReferenceByteArray)
{
//IV needs to be a 16 byte cryptographic stength random value
var iv = GetRandomValue();
//We will store both the encrypted value and the IV used - IV is not a secret
var indirectReferenceByteArray = new byte[OutputByteSize + IvSize];
using (SymmetricAlgorithm algorithm = GetAlgorithm())
{
var encryptedByteArray =
GetEncrptedByteArray(algorithm, iv, directReferenceByteArray);
Buffer.BlockCopy(
encryptedByteArray, 0, indirectReferenceByteArray, 0, OutputByteSize);
Buffer.BlockCopy(iv, 0, indirectReferenceByteArray, OutputByteSize, IvSize);
}
return HttpServerUtility.UrlTokenEncode(indirectReferenceByteArray);
}
private static string DecryptIndirectReferenceValue(
byte[] indirectReferenceByteArray)
{
byte[] decryptedByteArray;
using (SymmetricAlgorithm algorithm = GetAlgorithm())
{
var encryptedByteArray = new byte[OutputByteSize];
var iv = new byte[IvSize];
//separate off the actual encrypted value and the IV from the byte array
Buffer.BlockCopy(
indirectReferenceByteArray,
0,
encryptedByteArray,
0,
OutputByteSize);
Buffer.BlockCopy(
indirectReferenceByteArray,
encryptedByteArray.Length,
iv,
0,
IvSize);
//decrypt the byte array using the IV that was stored with the value
decryptedByteArray = GetDecryptedByteArray(algorithm, iv, encryptedByteArray);
}
//decode the UTF8 encoded byte array
return Encoding.UTF8.GetString(decryptedByteArray);
}
private static byte[] GetDecryptedByteArray(
SymmetricAlgorithm algorithm, byte[] iv, byte[] valueToBeDecrypted)
{
var decryptor = algorithm.CreateDecryptor(Key, iv);
return decryptor.TransformFinalBlock(
valueToBeDecrypted, 0, valueToBeDecrypted.Length);
}
private static byte[] GetEncrptedByteArray(
SymmetricAlgorithm algorithm, byte[] iv, byte[] valueToBeEncrypted)
{
var encryptor = algorithm.CreateEncryptor(Key, iv);
return encryptor.TransformFinalBlock(
valueToBeEncrypted, 0, valueToBeEncrypted.Length);
}
private static AesManaged GetAlgorithm()
{
var aesManaged = new AesManaged
{
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
return aesManaged;
}
private static byte[] GetRandomValue()
{
var csprng = new RNGCryptoServiceProvider();
var buffer = new Byte[16];
//generate the random indirect value
csprng.GetBytes(buffer);
return buffer;
}
} |
ÔÚÕâÀÎÒÃǵÄAPIÓ¦¸Ã¿´ÆðÀ´ÏñScopedReferenceMap£¬Ö»ÓÐÔÚ·¢Éú±ä»¯Ê±²Å»áÔÚÄÚ²¿ÔËÐУ¬ÎÒÃǽèÖúÁË.NET ÖоßÓÐ128Î»ÃØÔ¿µÄAesManaged¶Ô³Æ¼ÓÃÜ¿âºÍÒ»¸ö¶Ô³õʼÏòÁ¿£¨IV£©¸ß¶È¼ÓÃܵÄËæ»úÖµ¡£ÄãÃÇÖеÄһЩÈË¿ÉÄÜ»áÒâʶµ½£¬ÔõÑù²ÅÄÜ×öµ½ÔÚËÙ¶ÈÓëÇ¿¶ÈÖ®¼äµÄ×îÓÅ»¯ÄØ£¿
AesManagedÔÚʵÀýÖÐÒª±ÈFIPS¿ìÔ¼170±¶£¬Ï൱ÓÚAesCryptoServiceProvider
128볤¶ÈÐèÒªÖ´ÐÐËã·¨µÄ´ÎÊýÉÙÓÚ4´Î£¬ÕâÒª±È¸ü´óµÄ256볤¶ÈҪС
¹Ø¼üµãÖ®Ò»ÊÇÎÒÃÇΪ³õʼÏòÁ¿£¨IV£©Éú³ÉÒ»¸öÇ¿¼ÓÃܵÄËæ»úÖµ£¬Õâ¸öËæ»úÖµÓ¦Óõ½ÁËËùÓеļÓÃܹý³ÌÖС£ÃØÔ¿Í¬ÑùÊǸö»úÃÜ£¬ÎªÁ˱£ÃÜ£¬ÎÒÑ¡Ôñ½«ËüÁô¸øÄ㣬ÈÃÄãÀ´ÕÒ³öÄãÏëÔõÑùʹÓÃÃØÔ¿£¬ºÃµÄÒ»·½ÃæÊÇÎÒÃDz»±ØÓëÈκÎÈË·ÖÏíÃØÔ¿¡£×îÖÕ£¬ÎÒÃÇ´æ´¢´øÓÐÃÜÂëµÄ·Ç»úÃܵijõʼÏòÁ¿£¨¼ä½ÓÒýÓã©£¬ÕâÑùÎÒÃǾͿÉÒÔÔÚÒ»¸öÇëÇóÖнâÃܼä½ÓÒýÓá£
Òª¾ø¶ÔµØÇå³þ£¬Õâ²»ÊÇÒ»¸ö¿ÉÌæ´úµÄ·ÃÎÊ¿ØÖÆ¡£ÕâÖ»ÄÜÓûòÓ¦¸ÃÓÃÔÚÕýÈ·µÄ·ÃÎÊ¿ØÖÆÁ¬½ÓÉÏ¡£
ÏÖÔÚ£¬Ò²»¹ÓÐÒ»¸öûÓÐÄÇô¸´Ôӵķ½·¨¡£Ò»ÖָĽø¹ýµÄ·½·¨Êǰüº¬ÁËÉÏÊö¹ý³ÌµÄ¼ÓÃÜÈÏÖ¤£¨AE£©£¬µ«ÊÇÕâÊÇÒ»¸ö»ùÓÚ¹þÏ£ÏûÏ¢ÑéÖ¤ÂëµÄ¹ý³Ì¡£ÈÏÖ¤¼ÓÃÜÒ²Ö§³ÖÏñÌî³ä¡¢ÏûÏ¢´Û¸ÄµÈ±©Â©µÄ°²È«¹¥»÷¡£´ËÍ⣬Ïñ Stan DrapkinÄÇÑùµÄѧ×Å»á¸æËßÄã¶Ô³Æ¼ÓÃܱØÐë±»ÈÏÖ¤¼ÓÃÜ¡£
È»¶ø£¬Õâ²¢²»ÊÇһƪ¹ØÓÚ¼ÓÃܵÄÎÄÕ¡£ËùÓеijö·¢µã¾ÍÊÇÒÔ×îºóÒ»¸öÑ¡ÏîÀ´¡°ÕÕÁÁ¡±ÆäËûµÄÑ¡ÏĿµÄÊǸøÄÇЩ²»¼ä½ÓʹÓÃ×÷ÓÃÓòµÄÓû§»á»°£¬Èç.NET£¬Ìṩһ¸öÃô¸ÐÊý¾ÝµÄÄ£ºý»·¾³¡£
ÀμÇÕâЩ
»º½âºÍ¼õÉÙ²»°²È«µÄÖ±½Ó¶ÔÏóÒýÓõÄΨһ¿É¿¿µÄ·½·¨ÊǾßÓÐÊʵ±µÄ·ÃÎÊ¿ØÖÆ£¬ÔÙ¶àµÄ»ìÏý¶¼²»ÄÜ×èÖ¹¶ÔÊý¾ÝµÄδÊÚȨ·ÃÎÊ¡£
×ÊÁÏÊǷdz£ÖØÒªµÄ£¬¶ñÒâÓû§»áÒÔ¶ÔËûÃÇÓÐÀûµÄ·½Ê½À´Ê¹ÓÃËü£¬µ±ÄãÒâʶµ½µÄʱºò¾ÍÌ«ÍíÁË¡£Òò´Ë£¬µ±ÄãÈÏΪһÏîÊý¾ÝÊǸöÃô¸ÐÊý¾Ýʱ£¬ÄãÐèÒªÓ¦ÓÃÒ»¶¨µÈ¼¶µÄ»ìÏýÀ´½øÐм¼ÊõÉϵÄÏÞÖÆ£¬ÀýÈçʹÓÃÓû§»á»°¡£µ«ÊÇ»áÓÐÒ»¸ö.NET»á»°¿ªÏú£¬ËùÒÔÒªÖªµÀÄãÓ¦¸ÃÔõÑùÀûÓÃËü¡£
¾ø´ó¶àÊýÓ¦Óò¢²»ÐèÒª»ìÏýºÍ´´½¨¼ä½ÓÒýÓ㬵«ÊǶÔÓÚÏñ½ðÈڵȸ߶ÈÃô¸ÐµÄÍøÕ¾×îºÃ¼ÓÉÏÕâ²ã¶îÍâµÄ°²È«²ã¡£
×îºóÒ»µãÊÇ£º¶ÔÌØ¶¨Êý¾ÝÖµµÄ»ìÏýÖ»ÊÇÒ»¸öÄ£ºýµÄ°²È«¡£ËüÐèÒªÓëÆäËü°²È«´ëʩͬʱʹÓã¬ÀýÈçÕýÈ·µÄ·ÃÎÊ¿ØÖÆ¡£´ÓÕâ·½ÃæÀ´Ëµ£¬²»Ó¦¸Ãµ¥¶ÀÒÀÀµËü¡£
×ܽá
²»°²È«µÄÖ±½Ó¶ÔÏóÒýÓÃÖ÷񻃾¼°µÄÄÚÈÝÊÇ£¬Í¨¹ýºÏÀíµÄ·ÃÎÊ¿ØÖÆÀ´±£»¤Êý¾Ý²»±»Î´¾ÊÚȨµÄ·ÃÎÊ¡£Æä´Î£¬ÎªÁË·ÀÖ¹ÏñÖ±½ÓÒýÓüüÖµÄÇÑùµÄÃô¸ÐÊý¾ÝÔ⵽й¶£¬ÒªÁ˽âÈçºÎÒÔ¼°ºÎʱ¸Ãͨ¹ý¼ä½ÓÒýÓÃÄÇЩ¼üÖµÀ´Ìí¼ÓÒ»²ã»ìÏý¡£×îºó£¬ÔÚ¾ö¶¨ÒªÊ¹ÓûìÏý¼¼Êõʱ£¬ÒªÒâʶµ½ÀûÓüä½ÓÒýÓÃÓ³ÉäÀ´ÃÖ²¹Â©¶´µÄ¾ÖÏÞÐÔ¡£ |