I've been following this example to access azure active directory from an angular (4) application: https://github.com/benbaran/adal-angular4-example
I can authenticate to AD but then I want to make subsequent calls to an API / APP also registered in AD.
I have tried using this example:
public CallAPI() {
let headers = new Headers({ 'Content-Type': 'application/json' });
var token;
this.service.acquireToken("{client id}").subscribe(p => {
token = p;
headers.append("Authorization", 'Bearer ' + token);
let options = new RequestOptions({ headers: headers });
// Make the HTTP request:
this.httpClient.get('https://localhost:45678/stuff', options).subscribe(data => {
// Read the result field from the JSON response.
this.results = data['results'];
console.log(data);
});
}, (error => {
console.log(error);
}));
}
The first issue I have is a CORS error. I am running the client app on localhost:and get:
XMLHttpRequest cannot load https://localhost:45678/stuff. Redirect from 'https://localhost:45678/stuff' to 'https://login.microsoftonline.com/..........' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:4200' is therefore not allowed access.
The app / API I am trying to access is also running locally (both client and server are https)
They are both registered applications in active directory and their signon/app id uris are set to their respective localhost addresses.
The app / api uses service stack and is setup thus:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudience = Audience
},
Tenant = Domain
});
public override void Configure(Container container)
{
AddPreRequestFilters();
AddErrorResponseFilters();
this.Plugins.AddRange(ServiceConfiguration.GetPlugins());
this.Plugins.Add(new SwaggerFeature());
this.Plugins.Add(new CorsFeature(allowedHeaders: "Origin, X-Requested-With, Content-Type, Accept, Authorization", allowCredentials: true));
ServiceConfiguration.Configure(container);
}
To bypass the CORS error I used the Allow-Control-Allow-Origin
chrome extension, using this I get an OPTIONS request then a 302 (to my 'stuff' endpoint) which contains my authorization: Bearer {token}
header. Finally there is an OPTIONS and GET (with auth header) to login.microsoft.com/..../oath2...
This always fails to sign in.
My ADAL config looks like this:
const config: adal.Config = {
tenant: 'xxxx.onmicrosoft.com',
clientId: 'xxxxxxxxxxxxxx', // client id of AD app
redirectUri: 'https://localhost:4200/', // the angular app
cacheLocation: 'localStorage'
}
Is there anything obvious I am missing? I have also tried bypassing the acquireToken step using the endpoints property to no avail:
endpoints: {
'https://localhost:45678/': 'https://localhost:45678/' <-- the address of the API/APP I want to call
}
https://login.microsoftonline.com/
your code is redirecting the request to doesn’t send the Access-Control-Allow-Origin response header that’s needed for browsers to allow your frontend JavaScript code to access the response cross-origin. The only likely solution in this case is to not handle that login request from your frontend code but instead handle it from your backend code. The flow you’re trying to have it follow now is not going to work. – sideshowbarkerValidAudience
value in api app token validation logic ? – Nan Yu