Use Azure Storage Table REST API with AAD token via PostMan

Published Aug 18 2021 09:08 AM 1,489 Views
Microsoft

You can refer to below steps for scenarios in which you have an application special requirement and need to call raw Storage table REST API from your dev environment via Postman. It consists of two main HTTP requests: first, to authenticate directly using AD security principal to get access token, second an authenticated storage REST API call for Table Storage.

 

Documentation related

 

Prerequisites

 

To follow the steps in this article you must have:

  • Azure subscription
  • An Azure AD tenant
  • Registered application (AD Service principal)

 

Steps to reproduce this scenario:

 

  1. Acquire oAuth 2.0 token:

 

  1. Created security principal for application (Azure portal > AAD > app registrations). Documentation reference: https://docs.microsoft.com/en-us/rest/api/servicebus/get-azure-active-directory-token#register-your-...
  2. Assigned Storage Table Data Reader role at storage account level to SP created in step #1 (waited for 30 mins)jumontoy_0-1629297449879.png

     

  3. Used Postman to get the Azure AD token:

 

  • Launch Postman.
  • For the method, select GET.
  • For the URI, enter https://login.microsoftonline.com/<TENANT ID>/oauth2/token. Replace <TENANT ID> with the tenant ID value you copied earlier.
  • On the Headers tab, add Content-Type key and application/x-www-form-urlencoded for the value.

 

jumontoy_1-1629297449884.png

 

  • Switch to the Body tab and add the following keys and values.
  • Select form-data.
  • Add grant_type key, and type client_credentials for the value.
  • Add client_id key, and paste the value of client ID you noted down earlier.
  • Add client_secret key, and paste the value of client secret you noted down earlier.
  • Add resource key, and type https://storage.azure.com/ for the value

 

jumontoy_2-1629297449892.png

 

  • Select Send to send the request to get the token. You see the token in the result. Save the token (excluding double quotes). You will use it later

jumontoy_3-1629297449902.png

                                       

  1. Called Query Entities storage REST API and passed the oAuth 2.0 token from previous step

 

  • In Postman, open a new tab.
  • Select GET for the method.
  • Enter URI in the following format: https://<account>.table.core.windows.net /<table>(). Replace <account> with the name of the Storage Account name. Replace <table> with the name of the table.
  • On the Headers tab, add the following three headers.
  • Add Authorization key and value for it in the following format: Bearer <TOKEN from Azure AD>. When you copy/paste the token, don't copy the enclosing double quotes.

 

jumontoy_4-1629297449910.png

 

  • Select Send to get the entities from table. You see the status as OK with the code 200 as shown in the following image.

 

jumontoy_5-1629297449918.png

 

4 Comments
Microsoft

Azure.Data.Tables also now supports AAD auth out of the box against Storage Table endpoints - Sample

Occasional Visitor

Nice article!

Is it possible to get the token without the client secret?

I've been trying to use msal.js 2 to get the token but can't figure out which scope to use(.default) does not seem to work.

 

If I use user_impersonation (and grant this api permission to the app registration) it is working, but it is using the user's permissions and I don't want to grant the users access at the table level. I want to set permissions only through the app registration like in this article.

 

Any thoughts on this?

 

Many thanks,

Adrian

Occasional Visitor

Does this work for blobs as well? and i am unable to get it working as it says 'The required field 'scope' is missing from the credential, is scope required

Microsoft

@kedar2021 for this to be adapted to blob, it will require to adjust some aspects. For example: The role assigned to the security principal should be Blob based (Storage Blob Data Reader as minimum), also for the second part of the steps, it should be done against blob endpoint and call a blob REST API as per https://docs.microsoft.com/en-us/azure/storage/blobs/reference. Please share more details about your repro in order to understand better in which step of all the process are you seeing that message. Thanks in advance.

%3CLINGO-SUB%20id%3D%22lingo-sub-2660967%22%20slang%3D%22en-US%22%3EUse%20Azure%20Storage%20Table%20REST%20API%20with%20AAD%20token%20via%20PostMan%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2660967%22%20slang%3D%22en-US%22%3E%3CP%3EYou%20can%20refer%20to%20below%20steps%20for%20scenarios%20in%20which%20you%20have%20an%20application%20special%20requirement%20and%20need%20to%20call%20raw%20Storage%20table%20REST%20API%20from%20your%20dev%20environment%20via%20Postman.%20It%20consists%20of%20two%20main%20HTTP%20requests%3A%20first%2C%20to%20authenticate%20directly%20using%20AD%20security%20principal%20to%20get%20access%20token%2C%20second%20an%20authenticated%20storage%20REST%20API%20call%20for%20Table%20Storage.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3E%3CEM%3EDocumentation%20related%3C%2FEM%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EQuery%20Entities%20REST%20API%20-%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Frest%2Fapi%2Fstorageservices%2Fquery-entities%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Frest%2Fapi%2Fstorageservices%2Fquery-entities%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3EAuthorize%20access%20to%20tables%20using%20Azure%20Active%20Directory%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fstorage%2Ftables%2Fauthorize-access-azure-active-directory%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fstorage%2Ftables%2Fauthorize-access-azure-active-directory%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3E%3CEM%3EPrerequisites%3C%2FEM%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ETo%20follow%20the%20steps%20in%20this%20article%20you%20must%20have%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EAzure%20subscription%3C%2FLI%3E%0A%3CLI%3EAn%20Azure%20AD%20tenant%3C%2FLI%3E%0A%3CLI%3ERegistered%20application%20(AD%20Service%20principal)%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3E%3CSTRONG%3ESteps%20to%20reproduce%20this%20scenario%3A%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3EAcquire%20oAuth%202.0%20token%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%20class%3D%22lia-list-style-type-lower-alpha%22%3E%0A%3CLI%3ECreated%20security%20principal%20for%20application%20(Azure%20portal%20%26gt%3B%20AAD%20%26gt%3B%20app%20registrations).%20Documentation%20reference%3A%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Frest%2Fapi%2Fservicebus%2Fget-azure-active-directory-token%23register-your-app-with-azure-ad%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Frest%2Fapi%2Fservicebus%2Fget-azure-active-directory-token%23register-your-app-with-azure-ad%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3EAssigned%20%3CSTRONG%3E%3CEM%3EStorage%20Table%20Data%20Reader%3C%2FEM%3E%3C%2FSTRONG%3E%20role%20at%20storage%20account%20level%20to%20SP%20created%20in%20step%20%231%20(waited%20for%2030%20mins)%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_0-1629297449879.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304115i3CD9CB563450F108%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_0-1629297449879.png%22%20alt%3D%22jumontoy_0-1629297449879.png%22%20%2F%3E%3C%2FSPAN%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%3EUsed%20Postman%20to%20get%20the%20Azure%20AD%20token%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ELaunch%20Postman.%3C%2FLI%3E%0A%3CLI%3EFor%20the%20method%2C%20select%20GET.%3C%2FLI%3E%0A%3CLI%3EFor%20the%20URI%2C%20enter%20%3CA%20href%3D%22https%3A%2F%2Flogin.microsoftonline.com%2F%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Flogin.microsoftonline.com%2F%3C%2FA%3E%3CTENANT%20id%3D%22%22%3E%2Foauth2%2Ftoken.%20Replace%20%3CTENANT%20id%3D%22%22%3E%20with%20the%20tenant%20ID%20value%20you%20copied%20earlier.%3C%2FTENANT%3E%3C%2FTENANT%3E%3C%2FLI%3E%0A%3CLI%3EOn%20the%20Headers%20tab%2C%20add%20Content-Type%20key%20and%20application%2Fx-www-form-urlencoded%20for%20the%20value.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_1-1629297449884.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304114iD0B43A99B68FC58B%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_1-1629297449884.png%22%20alt%3D%22jumontoy_1-1629297449884.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ESwitch%20to%20the%20Body%20tab%20and%20add%20the%20following%20keys%20and%20values.%3C%2FLI%3E%0A%3CLI%3ESelect%20form-data.%3C%2FLI%3E%0A%3CLI%3EAdd%20grant_type%20key%2C%20and%20type%20client_credentials%20for%20the%20value.%3C%2FLI%3E%0A%3CLI%3EAdd%20client_id%20key%2C%20and%20paste%20the%20value%20of%20client%20ID%20you%20noted%20down%20earlier.%3C%2FLI%3E%0A%3CLI%3EAdd%20client_secret%20key%2C%20and%20paste%20the%20value%20of%20client%20secret%20you%20noted%20down%20earlier.%3C%2FLI%3E%0A%3CLI%3EAdd%20resource%20key%2C%20and%20type%20%3CA%20href%3D%22https%3A%2F%2Fstorage.azure.com%2F%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fstorage.azure.com%2F%3C%2FA%3E%20for%20the%20value%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_2-1629297449892.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304116i35BB0A3CF03ECC93%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_2-1629297449892.png%22%20alt%3D%22jumontoy_2-1629297449892.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ESelect%26nbsp%3B%3CSTRONG%3ESend%3C%2FSTRONG%3E%26nbsp%3Bto%20send%20the%20request%20to%20get%20the%20token.%20You%20see%20the%20token%20in%20the%20result.%20Save%20the%20token%20(excluding%20double%20quotes).%20You%20will%20use%20it%20later%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_3-1629297449902.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304118i351F63D06177E0D6%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_3-1629297449902.png%22%20alt%3D%22jumontoy_3-1629297449902.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3C%2FP%3E%0A%3COL%20start%3D%222%22%3E%0A%3CLI%3ECalled%20Query%20Entities%20storage%20REST%20API%20and%20passed%20the%20oAuth%202.0%20token%20from%20previous%20step%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EIn%20Postman%2C%20open%20a%20new%20tab.%3C%2FLI%3E%0A%3CLI%3ESelect%26nbsp%3B%3CSTRONG%3EGET%3C%2FSTRONG%3E%26nbsp%3Bfor%20the%20method.%3C%2FLI%3E%0A%3CLI%3EEnter%20URI%20in%20the%20following%20format%3A%26nbsp%3Bhttps%3A%2F%2F%3CACCOUNT%3E.table.core.windows.net%20%2F%3CTABLE%3E().%20Replace%26nbsp%3B%3CACCOUNT%3E%26nbsp%3Bwith%20the%20name%20of%20the%20Storage%20Account%20name.%20Replace%26nbsp%3B%3CTABLE%3E%26nbsp%3Bwith%20the%20name%20of%20the%20table.%0A%3CLI%3EOn%20the%26nbsp%3B%3CSTRONG%3EHeaders%3C%2FSTRONG%3E%26nbsp%3Btab%2C%20add%20the%20following%20three%20headers.%3C%2FLI%3E%0A%3CLI%3EAdd%26nbsp%3BAuthorization%26nbsp%3Bkey%20and%20value%20for%20it%20in%20the%20following%20format%3A%26nbsp%3BBearer%20%3CTOKEN%20from%3D%22%22%20azure%3D%22%22%20ad%3D%22%22%3E.%20When%20you%20copy%2Fpaste%20the%20token%2C%20don't%20copy%20the%20enclosing%20double%20quotes.%3C%2FTOKEN%3E%3C%2FLI%3E%0A%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_4-1629297449910.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304117i84F23546B0F7F30A%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_4-1629297449910.png%22%20alt%3D%22jumontoy_4-1629297449910.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ESelect%26nbsp%3B%3CSTRONG%3ESend%3C%2FSTRONG%3E%26nbsp%3Bto%20get%20the%20entities%20from%20table.%20You%20see%20the%20status%20as%26nbsp%3BOK%26nbsp%3Bwith%20the%20code%20200%20as%20shown%20in%20the%20following%20image.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22jumontoy_5-1629297449918.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304119i8CCB322D9F19BCAD%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22jumontoy_5-1629297449918.png%22%20alt%3D%22jumontoy_5-1629297449918.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-2660967%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22tablestorage.png%22%20style%3D%22width%3A%20224px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304120i49335796BB807E1B%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22tablestorage.png%22%20alt%3D%22tablestorage.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2660967%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20Storage%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3C%2FTABLE%3E%3C%2FACCOUNT%3E%3C%2FTABLE%3E%3C%2FACCOUNT%3E%3C%2FLI%3E%3C%2FUL%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2717748%22%20slang%3D%22en-US%22%3ERe%3A%20Use%20Azure%20Storage%20Table%20REST%20API%20with%20AAD%20token%20via%20PostMan%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2717748%22%20slang%3D%22en-US%22%3E%3CP%3EAzure.Data.Tables%20also%20now%20supports%20AAD%20auth%20out%20of%20the%20box%20against%20Storage%20Table%20endpoints%20-%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-sdk-for-net%2Fblob%2Fdf05d84fdc1842df1b3ec9031d4e28aef1de7cfb%2Fsdk%2Ftables%2FAzure.Data.Tables%2Fsamples%2FSample0Auth.md%23tokencredential%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%22%3ESample%3C%2FA%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2738742%22%20slang%3D%22en-US%22%3ERe%3A%20Use%20Azure%20Storage%20Table%20REST%20API%20with%20AAD%20token%20via%20PostMan%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2738742%22%20slang%3D%22en-US%22%3E%3CP%3ENice%20article!%3C%2FP%3E%3CP%3EIs%20it%20possible%20to%20get%20the%20token%20without%20the%20client%20secret%3F%3C%2FP%3E%3CP%3EI've%20been%20trying%20to%20use%20msal.js%202%20to%20get%20the%20token%20but%20can't%20figure%20out%20which%20scope%20to%20use(.default)%20does%20not%20seem%20to%20work.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20I%20use%20user_impersonation%20(and%20grant%20this%20api%20permission%20to%20the%20app%20registration)%20it%20is%20working%2C%20but%20it%20is%20using%20the%20user's%20permissions%20and%20I%20don't%20want%20to%20grant%20the%20users%20access%20at%20the%20table%20level.%20I%20want%20to%20set%20permissions%20only%20through%20the%20app%20registration%20like%20in%20this%20article.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAny%20thoughts%20on%20this%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EMany%20thanks%2C%3C%2FP%3E%3CP%3EAdrian%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2751656%22%20slang%3D%22en-US%22%3ERe%3A%20Use%20Azure%20Storage%20Table%20REST%20API%20with%20AAD%20token%20via%20PostMan%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2751656%22%20slang%3D%22en-US%22%3E%3CP%3EDoes%20this%20work%20for%20blobs%20as%20well%3F%20and%20i%20am%20unable%20to%20get%20it%20working%20as%20it%20says%20'The%26nbsp%3Brequired%26nbsp%3Bfield%26nbsp%3B'scope'%26nbsp%3Bis%26nbsp%3Bmissing%26nbsp%3Bfrom%26nbsp%3Bthe%26nbsp%3Bcredential%2C%20is%20scope%20required%3C%2FP%3E%3C%2FLINGO-BODY%3E
Co-Authors
Version history
Last update:
‎Aug 18 2021 09:08 AM
Updated by: