I'm trying to get calendars from Office 365 to use them in a REST API (WEB API 2).
I already tried a lot of stuff to generate the JWT, but for each try, I get another error.

My application is properly registred in Azure AAD, the public key is uploaded.

The last thing I tried was from this article : <https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow/>

In his example, I can generate the JWT from two differents ways, but I get the error : x-ms-diagnostics: 2000003;reason="The audience claim value is invalid '<https://outlook.office365.com>'.";error\_category="invalid\_resource"

Here is my code :

`

```
string tenantId = ConfigurationManager.AppSettings.Get("ida:TenantId");
            /**
             * use the tenant specific endpoint for requesting the app-only access token
             */
            string tokenIssueEndpoint = "https://login.windows.net/" + tenantId + "/oauth2/authorize";
            string clientId = ConfigurationManager.AppSettings.Get("ida:ClientId");

            /**
             * sign the assertion with the private key
             */
            String certPath = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/cert.pfx");
            X509Certificate2 cert = new X509Certificate2(
                certPath,
                "lol",
                X509KeyStorageFlags.MachineKeySet);

            /**
             * Example building assertion using Json Tokenhandler. 
             * Sort of cheating, but just if someone wonders ... there are always more ways to do something :-)
             */
            Dictionary<string, string> claims = new Dictionary<string, string>()
            {
                { "sub", clientId },
                { "jti", Guid.NewGuid().ToString() },
            };

            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            X509SigningCredentials signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);

            JwtSecurityToken selfSignedToken = new JwtSecurityToken(
                clientId,
                tokenIssueEndpoint,
                claims.Select(c => new Claim(c.Key, c.Value)),
                DateTime.UtcNow,
                DateTime.UtcNow.Add(TimeSpan.FromMinutes(15)),
                signingCredentials);

            string signedAssertion = tokenHandler.WriteToken(selfSignedToken);

            //---- End example with Json Tokenhandler... now to the fun part doing it all ourselves ...

            /**
              * Example building assertion from scratch with Crypto APIs
            */
            JObject clientAssertion = new JObject();
            clientAssertion.Add("aud", "https://outlook.office365.com");
            clientAssertion.Add("iss", clientId);
            clientAssertion.Add("sub", clientId);
            clientAssertion.Add("jti", Guid.NewGuid().ToString());
            clientAssertion.Add("scp", "Calendars.Read");
            clientAssertion.Add("nbf", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(-5)));
            clientAssertion.Add("exp", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(15)));

            string assertionPayload = clientAssertion.ToString(Newtonsoft.Json.Formatting.None);

            X509AsymmetricSecurityKey x509Key = new X509AsymmetricSecurityKey(cert);
            RSACryptoServiceProvider rsa = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;
            RSACryptoServiceProvider newRsa = GetCryptoProviderForSha256(rsa);
            SHA256Cng sha = new SHA256Cng();

            JObject header = new JObject(new JProperty("alg", "RS256"));
            string thumbprint = WebConvert.Base64UrlEncoded(WebConvert.HexStringToBytes(cert.Thumbprint));
            header.Add(new JProperty("x5t", thumbprint));

            string encodedHeader = WebConvert.Base64UrlEncoded(header.ToString());
            string encodedPayload = WebConvert.Base64UrlEncoded(assertionPayload);

            string signingInput = String.Concat(encodedHeader, ".", encodedPayload);

            byte[] signature = newRsa.SignData(Encoding.UTF8.GetBytes(signingInput), sha);

            signedAssertion = string.Format("{0}.{1}.{2}",
                encodedHeader,
                encodedPayload,
                WebConvert.Base64UrlEncoded(signature));

```

`

My JWT looks like this :

`

```
{
 alg: "RS256",
 x5t: "8WkmVEiCU9mHkshRp65lyowGOAk"
}.
{
 aud: "https://outlook.office365.com",
 iss: "clientId",
 sub: "clientId",
 jti: "38a34d8a-0764-434f-8e1d-c5774cf37007",
 scp: "Calendars.Read",
 nbf: 1512977093,
 exp: 1512978293
}

```

`

I put this token in the Authorization header after the "Bearer" string.

Any ideas to solve this kind of issue ? I guess I need a external point of view :)

Thanks