Jon Knight
Jon Knight

Reputation: 169

What should be in the "encryptedSecretValue" Parameter in an Azure app manifest?

I'm trying to use OAuth authentication with Exchange Web Services (EWS) against Office365. This is after having successfully used OAuth2 with the new RESTful Graph API, but finding that Graph API doesn't do what I need to do with a confidential client "app-only" flow (this is going to be used by a daemon process, so no user interaction).

After many hours of forehead banging on my desk, I discovered (I hope!) that EWS SOAP transactions with confidential client OAuth Authorization headers have to have bearer access tokens created using X.509 certificates, not just the client_id/client_secret that you can use with the RESTful Graph API. Otherwise the EWS SOAP fails with an 401 Unauthorized HTTP return, and an extra non-standard header called x-ms-diagnostics with the value:

2000001;reason="The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.";error_category="invalid_token"

Unfortunately the Azure management portal doesn't have a UI for managing these certificates, so you have to download, edit and then up load the app's manifest (a JSON file).

I've created a self-signed 2048bit X.509 certificate (using openssl generating a PEM file called cert.pem and a key in file called key.pem), and then generated a base64 encoded fingerprint from cert.pem using:

echo $(openssl x509 -in cert.pem -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64

I followed the instructions in Step 2 of this document to try to put the certificate into the manifest (alongside the existing Graph API client_id/client_secret settings as I still want to use the nicer/more modern RESTful Graph API where possible in the app). To do this I added a new array element data structure to the passwordCredentials array in the JSON file:

{
  "customKeyIdentifier": "<base64EncodedFingerprintFromAbove>",
  "keyId": "<guid>",
  "endDate": "2018-11-24T09:12:01.397205Z",
  "type": "AsymmetricX509Cert",
  "usage": "Verify",
  "value": "MIIDvTCC (lots of certificate) cskQ=="
}

However when I now try to upload the edited manifest using the Azure management portal, I get the error:

ParameterValidationException=Invalid parameters provided; BadRequestException=Encrypted secret cannot be empty and can be at most 1024 bytes. Parameter name: encryptedSecretValue;

There is no parameter called encryptedSecretValue in my manifest JSON file, and I can't find anything via Google on what this error means or what should go in this parameter.

So my question is: what should go into the app manifest JSON file to permit certificates to be used to gain a confidential client access token for OAuth authorization with EWS SOAP queries? Am I barking up the wrong tree? Also, assuming I can get this to work with SOAP, can I use the resulting access token with the RESTful Graph API calls as well as with EWS SOAP calls (ie mix and match Graph and EWS in the same daemon program)?

Upvotes: 1

Views: 437

Answers (1)

Dan Kershaw - MSFT
Dan Kershaw - MSFT

Reputation: 5838

passwordCredentials is for shared secret/password (and that is what is shown in the UI).

You need to use keyCredentials for X509/asymmetric key support. So wrap your JSON above with:

    "keyCredentials": [ 
       put your JSON block from above right here
    ]

In the future we hope to have UX that will totally simplify this painpoint, and enable simple upload of a certificate. However this is all we have right now.

Hope this helps,

Upvotes: 2

Related Questions