| At line 3 changed one line |
| This is an example shows how to renew an Azure SAS token configured on a user at [User Manager].\\ |
| This example demonstrates using the Azure Delegation settings to renew an Azure SAS token configured on a user at [User Manager]. For more info see: Authorize access to blobs using Microsoft Entra ID Link: [https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-access-azure-active-directory]\\ |
| The job is eligible for daily scheduling.\\ |
| At line 7 changed one line |
| User Azure Blob VFS with user delegation settings:\\ |
| User's Azure Blob VFS with user delegation settings (for more info see: [Azure Integration]):\\ |
| At line 9 changed one line |
| [attachments|azure_blob_user_delegation_settings.png]\\ |
| [attachments|Azure Integration/user_delegation_settings.png]\\ |
| At line 12 added 158 lines |
| !!Section 1.\\ |
| \\ |
| It loads the user's VFS file, parses it, and retrieves the previous SAS token expiry date.\\ |
| \\ |
| [attachments|find_azure_vfs_file.png]\\ |
| \\ |
| __!!!Configure __your user's VFS path at the Find task.\\ |
| \\ |
| [attachments|file_parse_azure_vfs_file.png]\\ |
| \\ |
| Parse the VFS XML file to retrieve the Azure SAS token expiration.\\ |
| \\ |
| {{{ |
| vfs_xml = {xml_parse_start}{file_contents}{xml_parse_end} |
| org_sas_token = {decrypt_start}{v_0_sas_token}{decrypt_end} |
| se_all = {split_start:&se=:1}{org_sas_token}{split_end} |
| se_end_index = {indexof_start:&:0}{se_all}{indexof_end} |
| se = {substring_start:0:{se_end_index}}{se_all}{substring_end} |
| sas_token_expire = {parse_start:yyyy-MM-dd'T'HH~..~mm~..~ss'Z'}{se}{parse_end} |
| difference = {math_start:l}{sas_token_expire}-{now}{math_end} |
| }}}\\ |
| \\ |
| [attachments|get_azure_sas_token_info.png]\\ |
| \\ |
| !!Section 2.\\ |
| \\ |
| Verify the expiration of the SAS token and store the refresh token. The refresh token must be saved each time and stored as a persistent variable.\\ |
| \\ |
| [attachments|jump_difference_greater_then_zero.png]\\ |
| \\ |
| Set the difference to zero if it is less than zero.\\ |
| \\ |
| [attachments|set_difference_as_zreo.png]\\ |
| \\ |
| Verify if the difference is less than two days.\\ |
| \\ |
| [attachments|check_if_difference_is_less_then_two_day.png]\\ |
| \\ |
| Determine whether the persistent variable is present. On the first run, it will not exist.\\ |
| \\ |
| [attachments|check_persist_variable.png]\\ |
| \\ |
| Check for the presence of the persistent variable.\\ |
| \\ |
| [attachments|check_azure_refresh_token.png]\\ |
| \\ |
| Persist the Azure's refresh token.\\ |
| \\ |
| {{{ |
| persist_azure_refresh_token = {decrypt_start}{v_0_azure_user_delegation_refresh_token}{decrypt_end} |
| }}}\\ |
| \\ |
| [attachments|save_azure_refresh_token.png]\\ |
| \\ |
| !!Section 3.\\ |
| \\ |
| This section retrieves the Access Token using the Azure Refresh Token to obtain the user delegation key.\\ |
| \\ |
| Construct the request body of the HTTP call.\\ |
| \\ |
| {{{ |
| client_id = {decrypt_start}{v_0_azure_user_delegation_client_id}{decrypt_end} |
| tenant_id = {decrypt_start}{v_0_azure_user_delegation_client_tenant}{decrypt_end} |
| client_secret = {decrypt_start}{v_0_azure_user_delegation_client_secret}{decrypt_end} |
|
| renew_refresh_token_post_data = client_id={client_id}&client_secret={client_secret}&refresh_token={persist_azure_refresh_token}&grant_type=refresh_token |
|
| blob_storage_account_name = {url_start:user}{decrypt_start}{v_0_url}{decrypt_end}{url_end} |
| }}}\\ |
| \\ |
| [attachments|azure_oauth_2_data.png]\\ |
| \\ |
| Retrieve the Access Token through the HTTP Task.\\ |
| \\ |
| {{{ |
| URL = https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token |
| POST Data = {renew_refresh_token_post_data} |
| Content-Type = application/x-www-form-urlencoded |
| }}} |
| \\ |
| [attachments|CrushTaskExample18/oauth2_http_task.png]\\ |
| \\ |
| Verify the HTTP response.\\ |
| \\ |
| [attachments|check_aouth2_http_response.png]\\ |
| \\ |
| Parse the HTTP response and build the request body for the HTTP call to get the delegation key. __!!! We must store the new refresh token to maintain offline access.\\ |
| \\ |
| {{{ |
| response = {json_parse_start}{http_response_log}{json_parse_end} |
| persist_azure_refresh_token = {refresh_token} |
| after_6_days_in_millis = {math_start:l}{now}+518400000{math_end} |
| sas_start = {rparse_start:yyyy-MM-dd'T'HH~..~mm~..~ss'Z'}{yesterday}{rparse_end} |
| sas_end = {rparse_start:yyyy-MM-dd'T'HH~..~mm~..~ss'Z'}{after_6_days_in_millis}{rparse_end} |
| delegation_key_post_body = <?xml version="1.0" encoding="utf-8"?>{n}<KeyInfo>{n} <Start>{sas_start}</Start>{n} <Expiry>{sas_end}</Expiry>{n}</KeyInfo> |
| |
| }}}\\ |
| \\ |
| [attachments|variables_for_delegation_key_call.png]\\ |
| \\ |
| !!Section 4.\\ |
| \\ |
| This section retrieves the user delegation key, constructs a new Azure SAS token, and replaces the old value with the new value in the user's VFS file.\\ |
| \\ |
| HTTP call to obtain the user delegation key:\\ |
| \\ |
| {{{ |
| URL = https://{blob_storage_account_name}.blob.core.windows.net/?restype=service&comp=userdelegationkey |
| Post Data = {delegation_key_post_body} |
|
| Headers: |
|
| x-ms-version = 2022-11-02 |
| Authorization = Bearer {access_token} |
| }}}\\ |
| \\ |
| [attachments|user_delgation_http_call.png]\\ |
| \\ |
| [attachments|check_response_code_user_delegation.png]\\ |
| \\ |
| Parse the response of the Azure User Delegation HTTP call. The response XML lacks the 'properties' type, so we include it for proper XML file parsing.\\ |
| \\ |
| {{{ |
| parse_response = {xml_parse_start}{replace_start:<UserDelegationKey:<UserDelegationKey type="properties"}{http_response_log}{replace_end}{xml_parse_end} |
| permission = rwdl |
| user_delgation_key = {Value} |
| }}}\\ |
| \\ |
| [attachments|user_delegation_parse_result.png]\\ |
| \\ |
| Construct the Azure SAS token.\\ |
| \\ |
| {{{ |
| azure_sas_string_to_sign = {permission}{n}{n}{sas_end}{n}/blob/crushftpdatalake2/folderkz{n}{SignedOid}{n}{SignedTid}{n}{SignedStart}{n}{SignedExpiry}{n}b{n}{SignedVersion}{n}{n}{n}{n}{n}https{n}{SignedVersion}{n}c{n}{n}{n}{n}{n}{n}{n} |
| signature = {sign_hmacsha256_start:{user_delgation_key}}{azure_sas_string_to_sign}{sign_hmacsha256_end} |
| azure_sas_token = sp={permission}&se={sas_end}&skoid={SignedOid}&sktid={SignedTid}&skt={SignedStart}&ske={SignedExpiry}&sks=b&skv={SignedVersion}&spr=https&sv={SignedVersion}&sr=c&sig={sign_hmacsha256_value} |
| azure_sas_token_encoded = {encrypt_start}{azure_sas_token}{encrypt_end} |
| }}}\\ |
| \\ |
| [attachments|construct_azure_sas_token.png]\\ |
| \\ |
| Swap the old Azure Sas token with the newly created one.\\ |
| \\ |
| {{{ |
| Find Text = <sas_token>{v_0_sas_token}</sas_token> |
| Replace With = <sas_token>{azure_sas_token_encoded}</sas_token> |
| }}}\\ |
| \\ |
| [attachments|replace_azure_sas_token.png]\\ |
| \\ |
| !!Section 5.\\ |
| \\ |
| This section covers the error handling using the Default Failure Task (see at [Handling Job Failures]). |
| \\ |
| [attachments|default_failure_task.png]\\ |
| \\ |
| Sample job.XML can be downloaded here: [attachments|job.XML]\\ |
| \\ |