一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 詳解.NET Core中的數據保護組件

詳解.NET Core中的數據保護組件

2020-06-02 14:08LamondLu ASP.NET教程

在本篇文章中我們給大家整理了關于返回主頁.NET Core中的數據保護組件的相關知識點內容,有興趣的朋友們參考下。

背景介紹

在 OWASP(開放式 Web 應用程序安全項目) 2013 年發布的報告中,將不安全的直接對象引用(Insecure Direct Object Reference)標記為 十大 Web 應用程序風險之一, 其表現形式是對象的引用(例如數據庫主鍵)被各種惡意攻擊利用, 所以對于Api返回的各種主鍵外鍵ID, 我們需要進行加密。

.NET Core 的數據保護組件

.NET Core 中內置了一個IDataProtectionProvider接口和一個IDataProtector接口。其中IDataProtectionProvider是創建保護組件的接口,IDataProtector是數據保護的接口。開發人員可以實現這 2 個接口,創建數據保護組件。
內置的數據保護組件

.NET Core 中默認提供了一個數據保護組件, 下面我們來嘗試使用這個默認組件來保護我們的數據。

例: 當前我們有一個Movie類,代碼如下, 我們期望當獲取Movie對象的時候,Id字段是加密的。

?
1
2
3
4
5
6
7
8
9
10
11
public class Movie
 {
  public Movie(int id, string title)
  {
   Id = id;
   Title = title;
  }
 
  public int Id { get; set; }
  public string Title { get; set; }
 }

首先我們需要在Startup.cs中ConfigureService方法中配置使用默認的數據保護組件。

?
1
2
3
4
5
public void ConfigureServices(IServiceCollection services)
 {
  services.AddMvc();
  services.AddDataProtection();
 }

這段代碼會啟用.NET Core默認的數據保護器。

然后我們創建一個MoviesController, 并在構造函數中注入IDataProtectionProvider對象, 然后使用這個Provider對象創建一個實現IDataProtector接口的數據保護器對象

?
1
2
3
4
5
6
7
8
9
10
[Route("movies")]
 public class MoviesController : Controller
 {
  private readonly IDataProtector protector;
 
  public MoviesController(IDataProtectionProvider provider)
  {
   this.protector = provider.CreateProtector("protect_my_query_string");
  }
 }

TIPS: 使用Provider創建Protector的時候,我們傳入了一個參數"protect_my_query_string", 這個參數標明了這個保護器的用途,你也可以把它就當成這個保護器的名字。

注意: 不同用途的保護器不能解密對方的加密字符串。, 如果使用了保護器A去解密保護器B生成的字符串,會產生以下異常CryptographicException: The payload was invalid.

然后我們在MovieController中添加2個Api, 一個是獲取所有Movies對象的,一個是獲取指定Movie對象的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[HttpGet]
 public IActionResult Get()
 {
  var model = GetMovies();
  
  var outputModel = model.Select(item => new
  {
   Id = this.protector.Protect(item.Id.ToString()),
   item.Title,
   item.ReleaseYear,
   item.Summary
  });
 
  return Ok(outputModel);
 }
 
 [HttpGet("{id}")]
 public IActionResult Get(string id)
 {
  var orignalId = int.Parse(this.protector.Unprotect(id));
 
  var model = GetMovies();
  
  var outputModel = model.Where(item => item.Id == orignalId);
 
  return Ok(outputModel);
 }

代碼解釋

  • 在獲取Movie列表的api中,我們使用了IDataProtector接口的Protect方法對Id字段進行了加密
  • 相應的在獲取單個Movie對象的api中, 我們需要使用IDataProtector接口的Unprotect方法對Id字段進行解密。

最終效果

首先我們調用/api/movies, 返回結果如下, id字段已經被正確加密了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
[{
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6ygyO6avkgI2teCQGZQShNwsxC9ApDdsnyYd1K5IyNHjhZcRoGd6W31se3W6TWM8H9UdLEPn4fJpS5uKkqUa0PMV6a0ZZHBQSnlGoisSnj29g",
 "title": "泰坦尼克號"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6wkMUYyzflIzy3CwoMhcaO-np2WOy4czIL3WZd2FWi7Tsy119tDeFq7yAeye4o2W-KmbffpGXnTDZzNv2QbCrAm7-AyEN35g3pkfAYHa3X7aQ",
 "title": "我是誰"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6x2AXM6ulCwts2-uQSfzIU8UquTz-OAZIl-49D5-CYYl5H4mfZH8VihhCBJ60MMrZOlZla9qvb8EIP6GYRkEap4nhktbzGxW0Qu5r3edm6_Kg",
 "title": "蜘蛛俠"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zDZeLtPIVlkRLCd_V6Mr2kTzWsCkfYgmS0-cqhFAOu4dUWGtx6d402_eKnObAOFUClEDdF4mrUeDQawE71DDa805umhbAvX2712i7UgYO5MA",
 "title": "鋼鐵俠"
}]

然后我們繼續調用api, 查詢鋼鐵俠的電影信息

?
1
/api/movies/CfDJ8D9KlbQBeipPoQwll5uLR6zDZeLtPIVlkRLCd_V6Mr2kTzWsCkfYgmS0-cqhFAOu4dUWGtx6d402_eKnObAOFUClEDdF4mrUeDQawE71DDa805umhbAvX2712i7UgYO5MA

結果也正確的返回了。

?
1
[{"id":4,"title":"鋼鐵俠"}]

帶過期時間的數據保護器(Limited Lifetime)

.NET Core默認還提供了一種帶過期時間的數據保護器, 這種數據保護器許多使用場景,最常用的場景就是當為一個重置密碼操作的Token設置失效時間, 這樣一旦超時的, Token就不能解密成功, 從而我們就可以認定重置密碼操作超時了。

.NET Core中, 我們可以使用IDataProtector接口的ToTimeLimitedDataProtector方法創建一個帶過期時間的數據保護器。

這里我們還是使用默認還是繼續以上面的例子為例, 代碼修改如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private readonly ITimeLimitedDataProtector protector;
 
 public MoviesController(IDataProtectionProvider provider)
 {
  this.protector = provider.CreateProtector("protect_my_query_string")
     .ToTimeLimitedDataProtector();
 }
 
 [HttpGet]
 public IActionResult Get()
 {
  var model = GetMovies(); // simulate call to repository
  
  var outputModel = model.Select(item => new
  {
   Id = this.protector.Protect(item.Id.ToString(),
          TimeSpan.FromSeconds(10)),
   item.Title,
   item.ReleaseYear,
   item.Summary
  });
 
  return Ok(outputModel);
 }

代碼解釋

  • 這里我們定義了一個ITimeLimitedDataProtector接口對象protector, 并在構造函數中使用ToTimeLimitedDataProtector方法,將一個普通的數據保護器轉換成了一個帶過期時間的數據保護器
  • 在獲取Movie列表的api中, 我們依然使用Protect方法來加密Id字段, 與之前不同的是,這里我們加入了第二個TimeSpan參數,這個參數表示了當前加密的有效時間只有10秒。

最終效果

現在我們重新運行項目,還是和之前一樣先調用/api/movies方法來獲取Movies列表, 結果如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
[{
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6yzbDbZ931toH32VC6Jqg8DWsrmiLrOxOFFViH4QWZne43jwSVzBjzJIfctYKZniZKNVbr50RRIZpW2fe9UtPajEzBhI-H32Effm-F0ColUaA",
 "title": "泰坦尼克號"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zDDVymvftZK9lKBIjEyuoNTzOEu0SC2-qfTy6quXir2S8f3A1r44f9Yz3Sd_cyLZUp-_4gfJAasMfE8_ngYLrJmdsjN9LZ0g4vox0WJLjiGA",
 "title": "我是誰"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zL-M2jzv2HCeTiHjevkXvI2216NERplp43TOjCXtj4S52ll68sLyQNtG2FhhWlsOmFGvYY5G4gm5SKfASMMgE1jBr20xc2b_djWdLhWLIxnA",
 "title": "蜘蛛俠"
}, {
 "id": "CfDJ8D9KlbQBeipPoQwll5uLR6wAoZKCHTG0lvgYS3If_0_eAD30a2YV8RjNagwLXUdCSKsO3kyS58hqDqAPHw_KHwNpd-hjDFl3hFPa8LOWHyk901oc6ZuSxwzxFlljaVreFA",
 "title": "鋼鐵俠"
}]

等待10秒鐘后,我們繼續調用api, 查詢鋼鐵俠的電影信息

?
1
/api/movies/CfDJ8D9KlbQBeipPoQwll5uLR6wAoZKCHTG0lvgYS3If_0_eAD30a2YV8RjNagwLXUdCSKsO3kyS58hqDqAPHw_KHwNpd-hjDFl3hFPa8LOWHyk901oc6ZuSxwzxFlljaVreFA

返回了錯誤信息CryptographicException: The payload expired at 9/29/2018 11:25:05 AM +00:00. 這說明當前加密的有效期已過, 不能正確解密了。

Tips: 使用Action Filter解密參數

在之前的代碼中,我們在獲取單個Movie的方法中,我們手動調用了Unprotected方法來解密id屬性

?
1
2
3
4
5
6
7
8
9
10
11
[HttpGet("{id}")]
 public IActionResult Get(string id)
 {
  var orignalId = int.Parse(this.protector.Unprotect(id));
 
  var model = GetMovies(); // simulate call to repository
  
  var outputModel = model.Where(item => item.Id == orignalId);
 
  return Ok(outputModel);
 }

下面我們改用Action Filter來改進這部分代碼。

首先我們創建一個DecryptReferenceFilter, 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DecryptReferenceFilter : IActionFilter
 {
  private readonly IDataProtector protector;
 
  public DecryptReferenceFilter(IDataProtectionProvider provider)
  {
   this.protector = provider.CreateProtector("protect_my_query_string");
  }
 
  public void OnActionExecuting(ActionExecutingContext context)
  {
   object param = context.RouteData.Values["id"].ToString();
   var id = int.Parse(this.protector.Unprotect(param.ToString()));
   context.ActionArguments["id"] = id;
  }
 
  public void OnActionExecuted(ActionExecutedContext context)
  {
 
  }
 }
 
 public class DecryptReferenceAttribute : TypeFilterAttribute
 {
  public DecryptReferenceAttribute() :
   base(typeof(DecryptReferenceFilter))
  { }
 }

代碼解釋

  • 這里DecryptReferenceFilter實現了IActionFilter接口, 并實現了OnActionExecuting和OnActionExecuted方法
  • 在DecryptReferenceFilter類中,我們注入了默認的數據保護器提供器,并在構造函數中初始化了一個數據保護器
  • 在OnActionExecuting中我們從RouteData中獲取到未解密的id字段, 然后將其解密之后,替換了之前未解密的id字段,這樣ModelBinder就會使用解密后的字符串來綁定模型。

最終修改

最后我們修改一下獲取單個Movie的api, 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
[HttpGet("{id}")]
 [DecryptReference]
 public IActionResult Get(int id)
 {
  var model = GetMovies();
 
  var outputModel = model.Where(item => item.Id == id);
 
  return Ok(outputModel);
 }

我們在獲取單個Movie的方法上添加了DecryptReference特性。

運行代碼之后,代碼和之前的效果一樣。

源碼地址:id_protector.rar

原文鏈接:https://www.cnblogs.com/lwqlun/p/9726191.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品成人片深夜 | 欧美另类老女人 | 欧美日韩国产成人综合在线影院 | 动漫美女被吸乳 | 亚洲同性男男gay1069 | 91色视| 国产一区二区三区久久小说 | 日本一区二区三区四区无限 | 俄罗斯freeⅹ性欧美 | 国产亚洲精品精品国产亚洲综合 | 911福利视频 | 国产 日韩 欧美视频二区 | 国产女王女m视频vk 国产农村一级特黄α真人毛片 | 四虎永久免费地址在线网站 | 欧美午夜网站 | 精品一区二区三区波多野结衣 | 99综合视频 | 免费看又黄又爽又猛的视频软件- | 寡妇快点好大好爽视频 | 国产精品66福利在线观看 | 日韩欧美亚洲一区二区综合 | 欧美春宫 | 亚洲国产精品久久网午夜小说 | 非洲一级毛片又粗又长aaaa | 国产一级黄毛片 | 调教女高中生第3部分 | 国产精品久久久久一区二区三区 | 韩国三级2020 | 亚洲久操 | 国产成人精品视频频 | 亚洲视频第一页 | 成熟女人50岁一级毛片不卡 | 青草青草伊人精品视频 | 欧美一级欧美一级高清 | xxxxxx性受| 精品人人做人人爽久久久 | 精品牛牛影视久久精品 | 深夜在线网址 | 国产午夜精品久久理论片小说 | 国产资源免费观看 | 久久机热免费视频 |