1

I've build a simple API App with a REST Service. Now I've enabled principal authentication in Azure App Service. I'm able to get my bearer token by C# code:

public static AuthenticationResult GetS2SAccessTokenForProdMSA()
{
        return GetS2SAccessToken(authority, resource, clientId, clientSecret);
}

static AuthenticationResult GetS2SAccessToken(string authority, string resource, string clientId, string clientSecret)
{
        var clientCredential = new ClientCredential(clientId, clientSecret);
        AuthenticationContext context = new AuthenticationContext(authority, false);
        AuthenticationResult authenticationResult = context.AcquireTokenAsync(resource, clientCredential).Result;
        return authenticationResult;
}

If I want to get my bearer token by JavaScript, e.g.:

$.ajax({
    url: 'https://login.microsoftonline.com/1640e15a-2d4c-4903-8b89-a00c52ac3c17/oauth2/token',
    type: 'POST',
    crossOrigin: true,
    data: 'resource=https://foobar' +
                '&client_id=68b9a002-d6f9-4732-9c9c-893b2c60ba42' +
                '&client_secret=<secret>' +
                '&grant_type=client_credentials',
    contentType: 'application/x-www-form-urlencoded',
    success: function (returndata) {
        alert(formData);
    },
    error: function (errordata) {
        alert(errordata.statusText);
    }
});

I get an error in Chrome saying:

No 'Access-Control-Allow-Origin' header is present on the requested resource

But in Fiddler I can see the successful answer with my bearer token (same error in Firefox, but not in IE 11).

Why is it not possible to request the token by an AJAX request?

Am I missing something?

Cheers

user2191213
  • 61
  • 1
  • 3
  • You're making a request to a different domain from the web page so you need to [allow CORS on the server](http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource) – stuartd Mar 06 '17 at 11:20
  • I've enabled CORS in the API App itself for sure. But how should I enable CORS for the URL https://login.microsoftonline.com/1640e15a-2d4c-4903-8b89-a00c52ac3c17/oauth2/token? – user2191213 Mar 06 '17 at 11:26
  • I don't understand, why I'm not able to request the bearer token from any URL. – user2191213 Mar 06 '17 at 11:29

1 Answers1

3

You can't acquire the token from front-end with client credentials.

Instead you must use the Implicit Grant Flow to get the access token in a fragment after a redirect, or pass it to the front-end from the backend of your app.

Here you can find an example AngularJS app: https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp.

Another alternative is to just not call APIs from the front-end, but call them from your back-end.

The reason for the error is that Azure AD does not allow CORS.

By the way, never put your client secret in the front-end.

juunas
  • 54,244
  • 13
  • 113
  • 149
  • Thank you for your support! What is the best practice for calling an Azure API App WebService from a Webpage without Azure AD Authentication? Webpage is public, but WebService call should be invoked as a kind of an Service User. – user2191213 Mar 06 '17 at 11:34
  • Your front-end can call a public endpoint on its back-end. The endpoint can then authenticate with Azure AD through client credential flow (client id + client secret), and call the web service with the access token. This way your client secret is kept secret, and you can control what can be done. You can cache the access token + refresh token so you don't need to authenticate every time from back-end. ADAL does that for you quite nicely. – juunas Mar 06 '17 at 12:05