由於我們的程式是服務類型的因此Client Credentials Flow就是為了沒有「Resource Owner(這裡指的是人)」介入的情況而使用的OAuth流程,但是!!就是這個但是!!微軟的IMAP、POP、SMTP都不支持Client Credentials Flow!!
2022/06/30 新增IMAP、POP、SMTP的Client Credentials Flow!直接使用就對了!【點我前往參考連接】
另外微軟官方給的兩種方式,因此我們只剩下下面兩種選擇
前置準備1 - 添加Office 365 Exchange Online IMAP權限
使用Client Credentials Flow之前需要先做一些額外的設定,首先要添加Office 365 Exchange Online的API權限
選擇「我的組織使用的API」頁簽並在搜尋欄裡面輸入Office 365的關鍵字後即可找到「Office 365 Exchange Online」
確定點選的是Office 365 Exchange Online之後選擇應用程式權限並且找到IMAP將它打勾
前置準備2 - 使用Exchange Online進行應用程式註冊和郵箱授權
使用Exchange Online之前需要安裝ExchangeOnlineManagement【點我前往安裝方式】,安裝完成後要匯入EXO V2的模組
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName <管理者帳號>
New-ServicePrincipal -AppId <應用程式識別碼> -ServiceId <物件識別碼> -DisplayName <隨便取名即可>
Get-ServicePrincipal
Add-MailboxPermission -Identity "指定的郵箱帳號" -User <ServiceId> -AccessRights FullAccess
Get-EXOMailboxPermission -Identity "指定的郵箱帳號"
元件準備
- TsgcHTTP_OAuth2_Client
另外加上一個TButton,畫面直接奉上
在Use Client Credentials Flow - Button的OnClick事件啟動TsgcHTTP_OAuth2_Client元件
procedure TFormIMAPTest.btn_Client_Credentials_FlowClick(Sender: TObject);
begin
DoLog('Start Client Credentials Flow');
OAuth2_Client_Credentials.Start;
end;
實作Client Credentials Flow做授權驗證
TsgcHTTP_OAuth2_Client需要設定一下OAuth的屬性
- OAuth2Options:
- Client ID:用戶識別碼,直接帶入Azure AD的應用程式識別碼
- Client Secret:用戶識別密碼,直接帶入Azure AD的應用程式密碼
- Grant Type:授權方式,直接選擇auth2ClientCredentials💡 目前這個元件只支持Authorization Code Flow和Client Credentials Flow
- Password:無需設定
- Username:無需設定
- AuthorizationServerOptions:
- AuthURL:無需設定,Client Credentials不需要Auth驗證的流程因此不需要AuthURL
- Scope:請求的權限,我們要取得IMAP的權限因此設定「https://outlook.office365.com/.default」這組即可💡 在Azure AD上使用Client Credentails的Scope不管要取得什麼權限幾乎都是XXXX/.default結尾,不是這組Scope的話會回傳給你400錯誤
- TokenURL:驗證成功後取得Token的URL,需要包含TenantID💡 https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token
屬性設定完成後接著是事件,走Client Credentials Flow的話就只會有回傳AccessToken的動作這裡就跟Authorization Code Flow不太一樣直接加入OnAfterAuthorizeCode,另外如果想要知道錯誤的話也可以加入OnErrorAuthorizeCode和OnErrorAccessToken
procedure TFormIMAPTest.OAuth2_Client_CredentialsAfterAccessToken(
Sender: TObject; const Access_Token, Token_Type, Expires_In, Refresh_Token,
Scope, RawParams: string; var Handled: Boolean);
begin
DoLog('AccessToken: ' + Access_Token + CRLF +
'Token_Type: ' + Token_Type + CRLF +
'Expires_In: ' + Expires_In + CRLF +
'Refresh_Token: ' + Refresh_Token + CRLF +
'Scope: ' + Scope);
TIdSASLXOAuth(xOAuthSASL.SASL).Token := Access_Token;
TIdSASLXOAuth(xOAuthSASL.SASL).ExpireTime := Expires_In;
TIdSASLXOAuth(xOAuthSASL.SASL).User := '你剛剛使用Exchange Online設定的郵件帳號';
end;
執行Client Credentials Flow
完成!是不是走Client Credentials簡單很多呢XD總結
雖然我覺得Client Credentials Flow是再適合不過我們目前的需求的OAuth流程,但是既然微軟不支援那也沒辦法了XDD
由於微軟開放了Client Credentials Flow對於IMAP的驗證支援,我們的Client端只需要ClientID和Client Secret就可以操作指定的郵箱,對比ROPC(Resource Owner Password Credentials)還是需要使用者的密碼來說真的安全很多,只是Client Credentials Flow的前置設定很麻煩就是了XD
參考資料:
程式碼下載:【Delphi-OAuth2IMAP】
0 Comments
張貼留言