Dynamics CRM Web API from external site (javascript) - javascript

I'm currently developing a javascript app and I'm trying to access the Dynamics CRM Web API to fetch some information from the CRM.
My app hosted inside an Azure App Service (and testing in localhost), and it's accessible only authenticated users (by microsoft), so when users try to load the app, the azurewebsites redirect them to the microsoft's common OAUTH login page (https://login.microsoftonline.com/common/oauth2/authorize?...).
After a successful login, users redirect back to my javascript app, and then when the document is ready, I would like to call the dynamics CRM web api to fetch some entity (via jQuery's ajax request), but I get the following error message in the JS console:
XMLHttpRequest cannot load https://MYTENANTID.crm4.dynamics.com/api/data/v8.1/contacts. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://MYAPP.local' is therefore not allowed access. The response had HTTP status code 401.
I know this is bacause of the same origin policy, the question is: is it possible access the API from client side at all, or I need to do it in a server side?

According to your error message, it seems to be a common CORS issue when we calling a request from the client side application to our backend server.
Usually, we will add response headers in backend server to support the CORS. And you can refer to https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api for more info about how to enable Cross-Origin Requests in ASP.NET Web API.
And CRM 2016 has support CORS setting, please refer to https://msdn.microsoft.com/en-us/library/gg309589%28v=crm.8%29.aspx?f=255&MSPPError=-2147217396#bkmk_corsSupport for more info.

Related

Authorize attribute in dot net core controller protected by oidc

I have MVC dot Net Core app 2.0. The App authenticates against IdentityServer4 using Hybrid grant, so I have:
services.AddAuthentication(o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{......
and this works fine.
I also have a JavaScript client which authenticates against same IDP using implicit grant and that also works fine. I wanted to allow the javascript client calling an API (controller inside the MVC app) passing bearer token.
If that API has an Authorize attribute I am getting:
Failed to load http://localhost:4444/testidentity: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5003
I have CORS taking care off and the call works if I do not require Authorization at the API controller level.
I can easily move API into a separate project and having in the API something like:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{.......
This would work, but I would like to have it working in the MVC app and apparently missing some middleware configuration.
I guess your MVC app using openid bearer and cookies authentication, make sure to have the API (controller in MVC app) authentication schema as "bearer" then it will look for a bearer token in the request (regardless whose calling the API passing your CORS policy defined for your app) and verifies as per your middleware configuration for bearer token validation.
Also make sure, the access token has MVC app required scope to call controller.
I guess you will need something like below
[Authorize(AuthenticationSchemes =
JwtBearerDefaults.AuthenticationScheme)]
For more information refer this
It sounds like you are making a HttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
Quoted from Cross-Origin XMLHttpRequest:
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
Identityserver 4 needs to be configured for CORS. I suspect you need to add something like this Allowing Ajax calls to the Web API with CORS

Calling AAD Authenticated Azure function from Javascript without ADAL? No Access-control-allow-origin header is present

Is it possible to call an AAD authenticated Azure function from javascript without an auth library like ADAL and also without registering the client application with Microsoft?
Getting this error: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '
Both the simple web client app and azure function are registered under the same AAD. Both have the azurewebsites.net domain.
What's the lightest web client we can have?
The error you are getting is coming from a cross-origin resource sharing (CORS) check. I suspect this occurs when calling the function from the web app. The idea is that the browser is making an OPTIONS request first to see if the caller (the web app) is allowed to make a call a resource on a different domain (the function app). If that's approved, then it will make the actual call to the function.
So, we just have to make it so that the function app responds letting the browser know the call is allowed. Fortunately, Functions has a built-in CORS feature. In the portal, select Platform features for your function app. Under the API section, you'll see a CORS option. Add the domain for your function app and click Save. You should see the Access-Control-Allow-Origin error go away.
As for AAD, any OpenID Connect client library would work - ADAL is a fine choice for this, though. You may still need to create a client registration, though.
In Azure AD ,with the normal OpenID Connect/OAuth flow, you would acquire token by making a request to the /token endpoint. However, the azure ad endpoint does not support CORS requests, so making AJAX calls to get access tokens is out of the question. Instead, you can use the implicit flow in a hidden iframe to get new tokens for web APIs . See document here and here for more details .
And yes,i would suggest you use ADAL.JS which helps you to use Azure AD for handling authentication easier .

No 'Access-Control-Allow-Origin' for public api request

I'm trying to perform an ajax request to a third party api from my web site using javascript (On the client side) and I receive a No 'Access-Control-Allow-Origin' error. When trying to access this from node.js project everything is working fine.
More over, when opening Chrome with --disable-web-security everything is working fine as well.
Any information about this issue will be appreciated :-)
You cannot access a third-party API without using CORS. CORS adds special headers (e.g. Access-Control-Allow-Origin) to the HTTP response. This makes sure, that the API can control which front-end can make a request to it. This means, however, your API needs to recognize your front-end URL and accept requests from it.
You can (a) use CORS on the API side (changes are necessary on the API) or (b) use your server-side language to make the API request (e.g. PHP makes the request to the API and the front-end receives the response from the PHP back-end). Everything else is prohibited by the browser's security settings.
You can read more about CORS e.g. here.

Power BI API Authentication

How can I call the Power BI API from my application and understand Microsoft APIs?
I have successfully authorized users via the Azure AD library for JavaScript. However I have not been able to get a successful response from the API in the console. I get an unauthorized error, no access control allow origin header is present on the requested resource.
I am used to making API calls using Javascript and Angular, but not with Microsoft APIs and how they must be authorized. I have tried to read articles but they go over my head.
The errors are as follows
Failed to load resource: the server responded with a status of 404 (Not Found)
XMLHttpRequest: cannot load https://api.powerbi.com/v1.0/myorg/dashboards. Response to preflight request doesn't pass access control check: No Access-Control-Allow-Origin header is present on the requested resource. Origin http://renniesb.github.io is therefore not allowed access. The response had HTTP status code 404.
nope
Repository with my project code
https://github.com/Renniesb/sample_dashboard/tree/gh-pages
Place in repository that shows my Power B.I API call https://github.com/Renniesb/sample_dashboard/blob/gh-pages/app/services/powerbi.service.js
Expected behavior
List dashboards in the console.
Test site
https://Renniesb.github.io/sample_dashboard. To test I authorize with my credentials. How would I let users of this forum test the behavior. How do I enable their credentials?
List of things I've tried already
Created a reverse proxy using the following website: http://shawnsimondeveloper.com/nodeproxyangular/
Used the JSONP hack to attempt to get around CORS problem.
Put in the origin of the call in the webconfig file.
Tested the site both locally and on a webpage on GitHub
You shouldn't need to use both CORS and the HTTP proxy. Since you are using the ADAL JS library it will automatically append your Power BI token to your outgoing HTTP requests.
You will also need to setup the following:
Enable implicit grant flow as described in Step 3
Also, the dashboards endpoint is still only available in the "beta" version. This was causing the 404's.
Update your URLs to https://api.powerbi.com/beta/myorg/dashboards
To continue to use standard AJAX call with CORS:
Update your Angular powerbiService service to make HTTP requests directly to the https://api.powerbi.com domain rather than relative urls.

Google cloud print API key

I would like to call /search api from javascript client side. To do so, I have read that I need a oauth2 access token.
Following the Google guide, I must go to Google cloud Console but there is no Google Cloud Print service to subscribe to.
What service should I use to obtain an API key?
I recently started getting familiarized with both Google Cloud Print and OAuth, so I don't know much. I started in the same way that you seem to be starting. That is, by trying to make a successful request to /search. I will describe what worked for me.
After creating the project in the Cloud Console, I went to APIs & auth > Credentials menu item and created a new client ID for a 'Web Application' application type.
For the created client ID, I modified the Javascript Origins and the Redirect URIs appropriately.
Then, I added an anchor to the following URL in my web application so that the user gets directed to the authentication page.
https://accounts.google.com/o/oauth2/auth?
response_type=token&
client_id=<application-client-id>&
scope=https://www.googleapis.com/auth/cloudprint&
redirect_uri=<application-redirect-uri>
client_id - should be the client_id value of the Client ID that you registered in the Google Cloud Console.
response_type - This value would depend on what kind of application are you planning to develop. For client side applications (JavaScript apps), token should be the value. See https://developers.google.com/accounts/docs/OAuth2 for more info on this topic.
redirect_uri - should be the redirect URI value that you specified in the Client ID that you registered in the Google Cloud console. This is where the user will get redirected when it gets authenticated.
scope - I set it to https://www.googleapis.com/auth/cloudprint. This value will request that your app be given access to manage the cloud printers associated with the user account that is being authenticated.
Now, the part where I got stuck is when trying to make the HTTP request using JavaScript (AJAX) to https://www.google.com/cloudprint/search. I get the follow response when I attempt to make the HTTP request to /search.
OPTIONS https://www.google.com/cloudprint/search No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
It seems like the entity (server(s)) that is handling the request to the /search interface is not configured to use CORS? Correct me if I am mistaken.
Now, the way that I verified that I was able to successfully authenticate was by attempting the request to /search in a Java program instead. I used the OAuth token that I got when authenticating using my web app in a java program and made the request with the Authorization: OAuth <token> header set) and the request was successful.

Categories

Resources