I'm building a browser based application in Javascript. I've tried to access the docusign api via jQuery:
$.support.cors = true;
$.ajax({crossDomain:true, url:"https://demo.docusign.net/restapi/v2"})
I get the error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://demo.docusign.net/restapi/v2?_=1407189114238. This can be fixed by moving the resource to the same domain or enabling CORS.
Accessing other APIs such as yahoo, totally works:
$.ajax({crossDomain:true, url:"https://query.yahooapis.com/v1/public/yql"})
Is there a special thing that I need to do for docusign api? Thanks. (Note: My examples here use blank queries to illustrate whether an api is accessible at all. The actual code uses real queries. This problem is not caused by not having a real query. You can see this yourself by pasting the above url into your browser and see that it returns some xml.)
DocuSign does not support CORS (Cross-Origin Resource Sharing) in its platform. There are too many potential security risks with CORS and for DocuSign to maintain its extremely high level of security and certification compliance it can not support CORS.
Related
I've developed simple REST API using a expressJs. I'm using React as my client side application. So the problem is anyone can see my API endpoints because of react app is in client side. So they will also able to make request and fetch data from my REST API. (May be they will build their own client side apps using my API.) I've seen some question about this and couldn't find any comprehensive answer. How these kind of a security problem should be handled? Is it possible to give the access for API to only my client app? If not how huge brands that using REST API prevent that? (Also I don't have a user authenticating scenario in my product as well. People can just visit and use the website. They don't need to register).
Authentication can be a way but it can be bypassed. Another way is you can create a proxy server which strictly blocks cross origin requests, hence it blocks requests from other domains to make request to your API, and you can make your API call from that proxy server. In this way your API server endpoint will also be not compromised.
If, as you state in your comment, this is about users on your own website being allowed to use your site's API, while disallowing off-site use (e.g. other websites, wget/curl, etc) then you need to make sure to set up proper CORS rules (to disallowed cross-origin use of your API) as well as CSP rules (to prevent user-injected scripts from proxying your API), and you also make sure to only allow API calls from connections that have an active session (so even if you don't want user authentication: use a session managemer so you can tell if someone landed on your site and got a session cookie set before they started calling API endpoints).
Session management and CORS come with express itself (see https://expressjs.com/en/resources/middleware/session.html and https://expressjs.com/en/resources/middleware/cors.html), for CSP, and lots of other security layers like HSTS, XSS filtering, etc, you typically use helmet.
I'm working on a submission for a conference. I'd like to integrate DocuSign with Alfresco's Angular based developer framework and specifically the Alfresco Content App.
In order to keep things simple, I'd like to think about workflows that could be done 100% from the browser without any backend code of my own.
I suspect I could create a "Sign this document now" type action for any document found in the Alfresco UI. That could initiate an OAuth flow that would not require any backend services of my own.
I think I would need to put my integrator key into the SPA. This would then be visible to anyone using the app. From reading through docs, I'm unclear if it is OK to "leak" this key?
Are there other use cases I can implement in an SPA without adding backend services of my own? Things like, sending a doc out to be signed by one or more people? Or embedding a signing experience in the Angular UI?
I have seen the following series on the DocuSign blog:
https://www.docusign.com/blog/dsdev-building-single-page-applications-with-docusign-and-cors-part-1/
Having read through that and also the REST API documentation, I'm still unclear if it is even possible to implement something like this without any support from my own backend service.
I also have not found any place online where I can reach out to a developer evangelist from DocuSign to discuss my options. I believe DocuSign developers monitor SO, so figured this was the next best thing.
Great question. Browsers implement the Same Origin Policy. So, as I wrote in the blog series (see all three of my posts listed below), you will need a CORS gateway to make API calls from your Angular program running in the browser itself to the DocuSign system.
The good news is that creating a private CORS gateway isn't hard. See part 2 of the series:
Part 1. Introduction
Part 2. Building a private CORS gateway
Part 3. An example React SPA
Authentication
Your app will need an access token when it makes API calls to DocuSign. There are multiple techniques available to give your app the access token it needs:
Your app can, by itself, authenticate the user with DocuSign. In this case, because of the security issues--as you mentioned in your question--you do not use the OAuth Authorization Code Grant flow. Instead, you use the OAuth Implict Grant flow, which is designed for this use case. This flow is demonstrated in part 3 of the blog series.
You can implement the OAuth Authorization Code Grant flow in your server, and then create a private API between your server and your browser app to obtain the access token.
A private API
As an alternative to using CORS, you can just implement your own private versions of the DocuSign API methods on your server. Then your browser app would send a private_send_envelope request to your server. Your server would manage the access token, send the request to DocuSign, and relay the response back to your browser app.
This pattern is the same as your question about implementing a backend service. It will work fine but is not as elegant as implementing everything within your browser app. Depending on your immediate and future API needs by your SPA, this might be a good idea or not.
CORS support is the key
Until DocuSign has CORS support you'll need to build something on the backend. Either a CORS gateway (which only involves configuration, not software) or a private API gateway.
Please ask your DocuSign sales or technical contact to add your information to the internal DocuSign proposal for CORS support, PORTFOLIO-1100. This will help raise the priority of CORS support. Thanks.
Specific answers
Regarding:
I think I would need to put my integrator key into the SPA. This would then be visible to anyone using the app. From reading through docs, I'm unclear if it is OK to "leak" this key?
Answer: It is okay to add your integrator key (IK) to your browser app if and only if the IK is set for Implicit Grant usage (check the "Mobile App" checkbox on the IK's property sheet).
Having read through that and also the REST API documentation, I'm still unclear if it is even possible to implement something like this without any support from my own backend service.
Answer: at this time you will either need to implement a private CORS gateway or implement backend software.
We followed this project and wired up our MVC application to use the new ADAL bit but we are seeing the following error when the token expires:
XMLHttpRequest cannot load https://login.windows.net/0bccafdb-3696-4344-3269-991d0a93be57/oauth2/autho…QzLTk5MWUtOGE5KRLTIFMYWE3MTliNjU1YMJTLENi00YWIzLTllNDQtYmVmZWU4ZWFjMjQ1. The request was redirected to 'https://login.microsoftonline.com/login.srf?wa=wsignin1.0&wtrealm=https%3a%…ZAEkNmNhNzFiYTUtZWZhOS00YjE0LWExYTYtZjQ5NjgwMzU5NzEz7Q2&wp=MBI_FED_SSL&id=', which is disallowed for cross-origin requests that require preflight.
Related: CORS preflight request responds with 302 redirect in Azure hosted Web API
That sample is not meant to be used with XMLHttpRequest. It is secured via a redirect based protocol, which in turn requires full browser postbacks for performing authentication operations. That protocol is not designed to work with Web API and AJAX calls, and although it can work for testing purposes production use will force you into hacks and other bad tactical measures.
If you want to make calls from JavaScript, please consider http://www.cloudidentity.com/blog/2015/02/19/introducing-adal-js-v1/.
Running any of the sample REST API calls for O365 works fine with the sand-boxed URLs and authorization headers.
However, substituting these URLs with my own is no-go.
XMLHttpRequest cannot load https://****-my.sharepoint.com/_api/v1.0/me/files. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://****:44301' is therefore not allowed access. The response had HTTP status code 403.
Is the issue due to cross-domain scripting?
Extra authorization that must be done on a "real" O365 endpoint as opposed to the sandboxed sample?
Are these libraries used from web context ? It sounds like it from the problem description. Please note that these libraries will only work from Cordova app context for now. http://microsoft.response.lithium.com/portal/conversation/1003718
The purpose of this question is to confirm (or not) my understanding of the purpose of W3C Access Control. If I'm reading this correctly, it allows a resource to control who can access it from a page loaded from some other resource. It does not protect a page against malware injection making cross-script requests. In other words, any bad hat can create a (e.g.) restful service that cheerfully accepts stolen information, so long as it returns the headers from this spec to tell that browser that it is happy to do so. Have I missed anything?
Your understanding sounds correct. The CORS spec only details how code from one domain can access data from another domain, thereby getting around same-domain restrictions. The same security considerations as any other web request are still in effect with CORS, and you should trust the remote server you are loading data from. If you are implementing CORS on the server side, you should not rely on CORS as your sole security mechanism. If giving access to some protected resource, you should layer an auth mechanism such as OAuth2 on top of your CORS requests.