Latest Posts

2024年4月26日 星期五

使用LAPS保護本機管理員密碼

作者 : 何斯慕  精誠資訊/恆逸教育訓練中心資深講師


使用本機管理員密碼解決方案(LAPS),管理本機管理員帳戶密碼,防止本機管理員密碼洩密的風險,在Active Directory管理的網域中,防止本機管理員帳戶使用相同的密碼來存取網域中的所有系統和伺服器。這使得系統容易遭受到PtH攻擊,並允許攻擊者在網路上輕鬆橫向移動擴展攻擊,讓攻擊者能夠獲取企業管理員帳戶的敏感資訊。本機管理員密碼解決方案(LAPS)工具可協助網路防禦者在Active Directory (AD)中管理和儲存管理員密碼,透過定期自動更新密碼來幫助保護本機管理員密碼。
Microsoft LAPS的特點是使用群組原則,將加入網域的電腦作業系統上的本機管理員帳戶的密碼,自動定期變更產生複雜性的密碼,防止暴力破解密碼攻擊的威脅。LAPS允許為管理員帳戶設定單獨的密碼,並將密碼儲存在Active Directory (AD)目錄服務中,這些密碼可以在身份驗證時進行檢索存取,套用委派授權策略控制對這些本機管理員帳戶密碼的存取。LAPS只能管理本機管理員帳號,不支援本機管理員以外的其他帳戶/密碼更改,LAPS執行所有的管理工作,會使用安裝於受管理電腦上的群組原則用戶端延伸(CSE),才能正常有效的運作。


案例分析:

  1. 在網域中受管理的電腦安裝LAPS工具

2024年4月22日 星期一

在Blazor使用Fluent UI元件 - 1

作者:許薰尹  精誠資訊/恆逸教育訓練中心資深講師


Fluent UI Blazor 是一個由微軟開發的開源元件庫,可以讓程式開發人員在 Blazor 應用程式中使用 Fluent UI 來設計系統。Fluent UI 是一種設計套件,可幫助開發人員建立美觀、一致且易於使用的使用者介面。

 
Fluent UI Blazor 元件庫目前包含了超過 40 幾個元件,涵蓋了應用程式或網站中常見的使用者介面元素,例如按鈕、文字方塊、下拉式選單、表格、圖表等等。這些元件經過精心設計,可與 Fluent UI 設計系統的其餘部分無縫整合。

 
Fluent UI Blazor 元件庫的主要功能包括:
• 豐富的元件庫:包含超過 40 幾個常用元件,可滿足各種使用者介面需求。
• 易於使用:元件採用簡單易懂的 API,可快速上手,學習曲線短。
• 允許客製化:元件可根據需要進行客製化,以符合特定的設計的要求。
• 無障礙性:元件遵循無障礙性最佳做法,可供所有人使用。

 
Fluent UI Blazor 元件庫適用於以下場景:
• 建立新的 Blazor 應用程式。
• 將 Fluent UI 設計系統到用到現有的 Blazor 應用程式之中。
• 加速 Blazor 應用程式的使用者介面設計動作。

 
使用 Fluent UI Blazor 元件庫的優點包括:
• 可提高開發效率:使用現成的元件可節省開發時間和精力。
• 提升使用者體驗:Fluent UI 設計系統可幫助建立美觀、一致且易於使用的使用者介面。
• 降低維護成本:元件經過良好測試和維護,可降低應用程式的維護成本。

在這一篇文章中,我們將介紹一些適用於.NET 8,可在Blazor應用程式使用的Fluent UI元件基本功能。

安裝 Microsoft.FluentUI.AspNetCore.Templates套件
想要在Blazor應用程式之中開始使用 Fluent UI Blazor 元件進行設計的最簡單方法,就是利用官方提供的專案範本。專案範本可從以下網址下載:

https://www.nuget.org/packages/Microsoft.FluentUI.AspNetCore.Templates 

請參考下圖所示:


 

2024年4月10日 星期三

注意!保持PMP、ACP認證需要每3年60學分?快看如何更新


QPMP認證與ACP認證需要多久更新一次? 

PMP認證與ACP認證3年需要更新一次。3年內PMP認證需累積60PDU學分,ACP認證需累積30PDU學分,就可以更新;若3年沒有更新,有1年緩衝期,在緩衝期間達到累積學分即可更新認證,若超過緩衝期則要重考該認證。

QPMP、ACP認證有效日期該怎麼計算?

觀察2

若您100.1.1考上PMP認證(以證書日期為主),103.1.1前需要更新PMP認證,若無,103.1.1~104.1.1則為您的緩衝期,緩衝期間您的認證是無效的,PMI官網查詢到您的證書狀態為Suspend(暫停),若您在這一年內更新完成,您的第二張PMP證書的日期則為103.1.1~106.1.1;換言之,緩衝期的一年是不會影響您的證書起訖時間。

恆逸PDU系列課程為您提供全面的培訓,包含專案管理實務課程、敏捷管理課程、商業分析課程,也提供ITIL系列課程、藍隊資安、駭客資安、資安專家系列課程、國際標準系列課程,讓您在專業領域中脫穎而出。

更完整PDU課程資料請點選

2024年4月8日 星期一

使用Visual Studio Code設計ASP.NET Core Web API - 2

作者:許薰尹  精誠資訊/恆逸教育訓練中心資深講師

出刊日期:2024/3/20

本文將延續本站《使用Visual Studio Code設計ASP.NET Core Web API - 1》一文的情境,介紹如何在ASP.NET Core Web API專案中設計資料模型、資料服務,以及控制器的程式碼,以處理各種不同的HTTP請求,例如使用 CRUD 操作(新增、讀取、更新、刪除)處理資料。 

設計資料模型

 在設計 Web API 之前,我們需要提供執行作業的資料暫存區,通常會使用模型類別來代表,我們將加入一個「Book」類別代表圖書資料。 模型中定義代表圖書特性的屬性。 模型將應用在 Web API 中傳遞資料,以及用來將圖書資料保存在資料存放區中,在這個文章中我們會將資料放在本機記憶體內部快取之中。
接下來來設計設計「Book」模型。先在終端機視窗執行下列命令,建立「Models」資料夾:

 

1
mkdir Models



在 Visual Studio Code 開發工具中選取「Models」資料夾,並按下「New File」按鈕,新增一個名為「Book.cs」的新檔案。

 

 

圖 1:新增「Book.cs」檔案。


新增下列程式碼到「Book.cs」之中:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
namespace MyWebAPI.Models
{
  public class Book
  {
    public int Id { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public DateTime PublishDate { get; set; }
    public bool InStock { get; set; }
    public string Description { get; set; }
  }
}

 

 

設計資料服務


在終端機視窗執行下列命令來建立「Services」資料夾:

1
mkdir Services



在 Visual Studio Code 開發工具中選取「Services」資料夾,並新增一個名為「BookService.cs」的新檔案。然後加入下列程式碼,建立圖書資料服務:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using MyWebAPI.Models;
 
namespace MyWebAPI.Services
{
  public static class BookService
  {
    public static List<Book> Books { get; private set; }
 
    static BookService()
    {
      Books = new List<Book>() {
        new Book() {
           Id = 1 ,
           Title = " Essential Programming Language " ,
           Price = 250 ,
           PublishDate = new DateTime( 2019 ,1,2 ) ,
           InStock = true ,
           Description = "Essential Programming Language "  ,
         },
         new Book() {
           Id = 2 ,
           Title = " Telling Arts " ,
           Price = 245 ,
           PublishDate = new DateTime( 2019 , 4 , 15 ) ,
           InStock = true ,
           Description = " Telling Arts "  ,
         },
           new Book() {
           Id = 3 ,
           Title = " Marvel " ,
           Price = 150  ,
           PublishDate = new DateTime( 2019 , 2, 21 ) ,
           InStock = true ,
           Description = " Marvel "  ,
         },
          new Book() {
           Id = 4 ,
           Title = " The Beauty of Cook" ,
           Price = 450 ,
           PublishDate = new DateTime( 2019 ,12,2 ) ,
           InStock = true ,
           Description = " The Beauty of Cook "  ,
         }
    };
    }
 
     
    public static List<Book> GetAllBooks()
    {
      return Books;
    }
    public static Book? GetBookById( int id )
    {
      return Books.Find( book => book.Id == id );
    }
     
    public static void AddBook( Book book )
    {
      int newId = Books.Count + 1;
      book.Id = newId;
      Books.Add( book );
    }
     
    public static void DeleteBookById( int id )
    {
      Book bookToRemove = Books.Find( book => book.Id == id );
      if ( bookToRemove != null )
      {
        Books.Remove( bookToRemove );
      }
    }
 
    public static void UpdateBook( int id, Book book )
    {
      Book bookToUpdate = Books.Find( book => book.Id == id );
      if ( bookToUpdate != null )
      {
        bookToUpdate.Title = book.Title;
        bookToUpdate.Price = book.Price;
        bookToUpdate.PublishDate = book.PublishDate;
        bookToUpdate.InStock = book.InStock;
        bookToUpdate.Description = book.Description;
      }
    }  
  }
}

 


在終端機視窗命令提示字元執行下列命令,以建置應用程式:

 

1
dotnet build

 

這個命令的執行結果請參考下圖所示:



 



圖 2:建置應用程式。

 


設計控制器


在ASP.NET Core Web API中,控制器是一個用來處理來自用戶端的HTTP請求的類別。每個控制器可以包含一個或多個動作(方法),這些動作負責處理各種不同的HTTP請求,例如GET、POST、PUT等。

在 Visual Studio Code 開發工具中選取「Controllers」資料夾,並新增一個名為「BookController.cs」的新檔案,依照慣例,控制器類別名稱的字尾會加上 「Controller」字串。在「BookController.cs」檔案中加入以下程式碼:

 

1
2
3
4
5
6
7
8
9
10
11
12
using System;
using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
  [ApiController]
  [Route( "[controller]" )]
  public class BookController : ControllerBase
  {
 
  }
}

 

 


控制器是一個公開類別,通常繼承自「ControllerBase」類別,類別上方套用[ApiController] 和 [Route]。


取得所有圖書資料


控制器類別包含處理不同HTTP請求的方法,這些方法稱為「動作」,它們是公開方法,用來對應特定的HTTP請求。
我們要撰寫的第一個REST指令動詞為「GET」,讓用戶端能夠從API獲取所有圖書的資訊。我們可以利用內建的[HttpGet]屬性,來定義一個方法,負責從服務取回圖書清單,在「BookController」類別加入以下程式碼:

1
2
3
4
5
6
//Get All Books
    [HttpGet]
    public IActionResult GetAll()
    {
      return Ok( MyWebAPI.Services.BookService.GetAllBooks() );
    }


上述程式具有以下特點:

  • 僅回應標識[HttpGet]屬性的HTTP GET請求。
  • 回傳一個List 類型的IActionResult實例。
  •  「GetAll」動作會叫用服務來查詢所有圖書,並自動設定「Content-Type」為「application/json」來回傳資料。


讀取單一圖書資料

 
用戶端可能會需要查詢特定圖書的詳細資料,而不是整個圖書清單。為此,我們可以設計一個帶有「id」參數的「GET」動作。使用內建的[HttpGet("{id}")]屬性定義一個方法,從服務中取回特定的圖書資料。在「BookController」類別加入以下程式碼:

1
2
3
4
5
6
7
//Get Book by Id
    [HttpGet("{id}")]
    public ActionResult<Book> Get( int id )
    {
      var book = MyWebAPI.Services.BookService.GetBookById( id );
      return book != null ? Ok( book ) : NotFound( );
    }

 




Web API的路由系統會根據是否提供id,來決定叫用[HttpGet](無id)和[HttpGet("{id}")](帶有id)兩個方法。

建置並測試控制器資料查詢

 在終端機視窗命令提示字元執行下列命令以執行Web API程式:

1
dotnet run


這個命令的執行結果請參考下圖所示:

 

 

 

圖 3:執行Web API程式。

 
使用 .HTTP 檔案測試控制器

 
開啟 「MyWebAPI.http」檔案,在分隔符「###」下方加入以下兩個「GET」程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@MyWebAPI_HostAddress = http://localhost:5052
 
GET {{MyWebAPI_HostAddress}}/weatherforecast/
Accept: application/json
 
###
GET {{MyWebAPI_HostAddress}}/Book/
Accept: application/json
 
###
GET {{MyWebAPI_HostAddress}}/Book/1
Accept: application/json
 
###




選取「GET」上方的 「Send Request」命令傳送要求,此命令將會以 JSON 格式傳回所有圖書的清單,這個命令的執行結果請參考下圖所示:

 

 


圖 4:送出GET請求取回所有圖書資料。


按相同的方式測試最後一個「GET」請求,取回一本圖書資料,這個命令的執行結果請參考下圖所示:

 


圖 5:送出「GET」請求取「id」相符的圖書資料。




我們的 API 也會處理資料不存在的情況。 若再次呼叫 API,故意使用下列命令傳入無效的圖書id編號:

 

1
2
3
4
5
6
@MyWebAPI_HostAddress = http://localhost:5052
 
###
GET {{MyWebAPI_HostAddress}}/Book/100
Accept: application/json
###


這時將會傳回 「404 Not Found」錯誤,請參考下圖所示:

 

 

圖 6:「404 Not Found」 錯誤。


使用HTTP REPL 命令測試控制器

 
在 Visual Studio Code 開發工具中選擇「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令,以 .NET HTTP REPL 命令列工具,來送出HTTP 請求:

1
connect http://localhost:5052


這個命令的執行結果請參考下圖所示:

 

 

圖 7:使用.NET HTTP REPL命令測試控制器。

 

執行下列命令,查看端點:

1
 


執行下列命令,以前往「Book」端點:

1
cd Book


使用下列命令,透過「HttpRepl」送出「GET」請求:

1
Get


這些命令的執行結果請參考下圖所示:


 

 

圖 8:使用HTTP REPL 命令測試控制器。



ASP.NET Core中的CRUD動作

 
我們的圖書服務提供支援圖書清單的 CRUD(建立、讀取、更新、刪除)操作。這些操作是透過不同的HTTP指令動詞來實現的,並且在ASP.NET Core中,這些動詞由特定的屬性來對應。例如從服務取得一個或多個項目的HTTP GET指令動詞,會透過使用[HttpGet]屬性來標示相應的動作方法。同樣的道理,[HttpPost]可用來標示資料新增的動作方法;[HttpPut] 可用來標示資料修改的動作方法;[HttpDelete] 可用來標示資料刪除的動作方法;

 
「POST」動作

 
我們已經看過「GET」動作的運作方式, 現在就來深入了解「POST」、「PUT」和 「DELETE」動作。我們先使用「POST」方法,透過 Web API 新增圖書資料,在「BookController」類別加入以下程式碼:

1
2
3
4
5
6
7
// Add Book
    [HttpPost]
    public IActionResult AddBook( Book book )
    {
      MyWebAPI.Services.BookService.AddBook( book );
      return Created( $"/book/{book.Id}", book );
    }

 



「AddBook」方法上標註 [HttpPost],用來處理發送到 Book API 的 HTTP「POST」請求。和「Get」方法回傳圖書清單不同的是,這方法會回傳「IActionResult」。「IActionResult」使用戶端能夠了解請求是否執行成功,若成功便提供新建立的圖書「ID」。利用標準的 HTTP 狀態碼,「IActionResult」確保無論用戶端使用的程式語言或開發平台是什麼,都能夠輕鬆地實現與用戶端的整合。

 
「PUT」動作

 
修改或更新我們圖書的程式類似於之前實作的「POST」方法,但需要搭配使用[HttpPut]屬性。除此之外,除了需要更新的「Book」物件之外,還需要一個「id」參數。接著,使用「PUT」方法,透過 Web API 更新圖書。在「BookController」類別加入以下程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Update Book
    [HttpPut("{id}")]
    public IActionResult UpdateBook( int id, Book book )
    {
      var existingBook = MyWebAPI.Services.BookService.GetBookById( id );
      if (existingBook == null)
      {
        return NotFound();
      }
      book.Id = id;
      MyWebAPI.Services.BookService.UpdateBook( id, book );
      return NoContent();
    }

 

 



「DELETE」動作

 
Web API其中一個較簡單要實作的動作是「DELETE」動作,只接受圖書的「id」參數,以便從記憶體內部快取中移除。在「BookController」類別加入以下程式碼:

 

1
2
3
4
5
6
7
8
9
10
11
12
// Delete Book
    [HttpDelete("{id}")]
    public IActionResult DeleteBook( int id )
    {
      var existingBook = MyWebAPI.Services.BookService.GetBookById( id );
      if ( existingBook == null )
      {
        return NotFound();
      }
      MyWebAPI.Services.BookService.DeleteBookById( id );
      return NoContent();
    }

 

 

建置並執行完成的 Web API

 
我們已經完成Web API的設計了,現在讓我們來測試看看。在終端機視窗命令提示字元執行下列命令,建立並啟動 Web API:

1
dotnet run


然後使用「.HTTP」檔案測試已完成的 Web API,重新開啟「MyWebAPI.http」 檔案,使用下列命令來送出「POST」要求,以新增圖書:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@MyWebAPI_HostAddress = http://localhost:5052
 
POST {{MyWebAPI_HostAddress}}/Book/
Content-Type: application/json
Accept: application/json
 
{
  "id": 100,
  "title": "Book 100",
  "price": 100,
  "PublishDate" : "2021-01-01T00:00:00",
  "InStock": true,
  "Description": "Book 100 Description"
}
 
###


上述命令會傳回新建立的圖書,執行結果請參考下圖所示:

 

 

圖 9:新增圖書。

 

在終端機視窗命令提示字元執行下列命令,以 PUT要求來更新圖書:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@MyWebAPI_HostAddress = http://localhost:5052
 
PUT {{MyWebAPI_HostAddress}}/Book/1
Content-Type: application/json
Accept: application/json
 
{
  "id": 1,
  "title": "New Book 1",
  "price": 100,
  "PublishDate" : "2021-01-01T00:00:00",
  "InStock": false,
  "Description": "New Book 1 Description"
}
###


上述命令會傳回下列訊息,表示成功:

1
2
3
4
HTTP/1.1 204 No Content
Connection: close
Date: Thu, 29 Feb 2024 05:51:06 GMT
Server: Kestrel


這個命令的執行結果請參考下圖所示:

 

 

圖 10:修改資料。

 

在終端機視窗命令提示字元執行下列命令,以透過「DELETE」動作來刪除圖書:

 

1
2
3
4
5
@MyWebAPI_HostAddress = http://localhost:5052
 
###
 
DELETE {{MyWebAPI_HostAddress}}/Book/1

 

 



上述命令會傳回下列訊息,表示成功,請參考下圖所示:


 

圖 11:刪除圖書。

 

使用HTTP REPL命令測試已完成的 Web API

 
先在專案根目錄加入一個「data.json」檔案,包含要新增的資料,使用JSON格式:

1
{ "id" : 100, "title" : "Book 100", "price" : 100, "PublishDate" : "2021-01-01T00:00:00", "InStock" : true, "Description" : "Book 100 Description"}



在 Visual Studio Code 開發工具 中選擇 >「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令:

1
httprepl http://localhost:5052


執行下列命令,查看端點:

1
 


這些命令的執行結果請參考下圖所示:


 

 

圖 12:httprepl連線到服務。

 
執行下列命令,以前往「Book」端點:

1
cd Book


使用下列命令,透過「HttpRepl」送出 POST請求,利用「-f」參數指定資料所在的檔案:

1
POST -f data.json


這些命令的執行結果請參考下圖所示:

 

 

圖 13:新增資料。

 
接著我們修改「data.json」檔案,修改編號「1」的圖書「title」等資料:

1
{ "id" : 1, "title" : "Book 101", "price" : 100, "PublishDate" : "2021-01-01T00:00:00", "InStock" : true, "Description" : "Book 101 Description" }




重複之前的動作,在 Visual Studio Code 開發工具 中選擇 >「 Terminal 」> 「New Terminal」開啟一個新的整合式終端機,在其中輸入並執行命令:

1
httprepl http://localhost:5052


執行下列命令,查看端點:

1
 

這個命令的執行結果請參考下圖所示:


 

 

 

圖 14:httprepl連線到服務。

 
執行下列命令,以前往「Book」端點:

1
cd Book

執行下列命令,查看端點:
1
 

這時你應該可以看到一個{id}端點,請參考下圖所示:

 

圖 15:{id}端點。

 
使用下列命令,透過「HttpRepl」中送出「PUT」請求:

 

1
Put -f data.json

 
使用「get」命令取回修改結果,比對資料是否正確被修改:
 

1
get

這些命令的執行結果請參考下圖所示:


 

圖 16:修改資料。

 
重複之前的動作,在終端機視窗輸入並執行命令,刪除編號為「1」的資料:

1
delete 1

使用「get」命令取回圖書資料,比對資料是否正確被修改:
1
get

這些命令的執行結果請參考下圖所示: 




 

圖 17:刪除資料。

總結

 
在這一系列文章,我們介紹了如何在 .NET 平台上建立一個運行ASP.NET Core Web API的應用程式。這個Web API利用快取來建立、讀取、修改和刪除圖書資料。現在你已掌握了以下使用ASP.NET Core建立Web API的關鍵步驟:

  •  利用ASP.NET Core Web API範本建立一個Web API應用程式。
  •  建立一個繼承自ControllerBase類別的類別,該類別包含用於響應HTTP請求的方法。
  •  使用工具來測試Web API的運作。