How to create custom URL in apex to get Json response from third party application - salesforce

I am sending some perameters to the third party application using rest api In one of the perameter I am sending A URL, This URL will use by third party application to send a json response after 5 or 10 min. My question is how may i create that URL for third party app that they will use to send the response.

If the 3rd party can send HTTP headers too you could send to them the current user's session id. If that user is API enabled (checkbox in profile/permission set) - you could write an Apex REST service that accepts POSTs. They'd call it with Authorization: Bearer <session id here> and it could work very nice. This trailhead might be a good start for you. (or can you contact their developers and maybe agree to make a dedicated user in SF for them so they'd log in under their own credentials and send it back?)
If they cannot send any special headers (it'd have to be unauthenticated connection to SF) - maybe you could make a Visualforce page, expose it as Site and then page's controller can do whatever you need. Maybe you already have something public facing (community?), maybe it'd be totally new... Check https://developer.salesforce.com/docs/atlas.en-us.206.0.salesforce_platform_portal_implementation_guide.meta/salesforce_platform_portal_implementation_guide/sites_overview.htm
If none of these work for you - does the url have to ping back to Salesforce. Maybe you have control over another server that can accept unauthenticated requests like that and have that one then call SF. Bit like a proxy. You could even set something up fairly easily on Heroku.
Last but not least. This would be extremely stupid but if all else fails - in a sandbox enable Web-to-Case or Web-to-Lead and experiment with these. At the end of the day they give you an url you can POST to and pass a form with data. I think it'd have to be Content-Type: application/x-www-form-urlencoded and if you mentioned JSON they're likely to send it as application/json so might not work. If it works - you could maybe save the payload in Description field of Cases (special record type maybe?) and do something with it. I'm seriously not a fan of this.

Related

REST API in MEAN stack, passed id vs id from session

I'm building a web app using MEAN stack.
While building the REST API I see a lot of examples with the following endpoint
/api/contacts/:id
for GET, PUT and DELETE methods.
I did something different, I enabled session in the Express framework and now I can see the user document id (for mongoDB) under req.session.req.payload._id when I do a HTTP request which enables me to access the document.
That why I also don't need to expose the user document id in the URL when I do
a HTTP request.
My question is which method is better and safer to use?
Also, how can I get the user id in Angular to pass to the HTTP request in case I don't use sessions.
And a final one... I also use JWT as middle-ware before calling the function which updates the DB. This gives me some sense of security but wouldn't it be possible for a user with the correct token to do HTTP requests with different ids and by that getting, updating and deleting other users data?
This won't be possible with the current method I'm using (sessions)
When you need to pass the user ID to the endpoints then your client code will need to know that and it's the backend that needs to provide it somehow - either as part of the returned toked or usually as part of the response to a successful login request. The client can store it in a cookie or a local storage to use later.
It is not very practical, though, to have to provide the ID of the user in every route like:
/api/contacts/:id
When your users need to be able to access other users contacts then you may need to use the ID in the route and you may not want to have another set of routes for a situation when the user wants to manipulate his or her own contacts.
What I've seen sometimes done in practice in situations like this is to use a special value for the ID like "me" and have your backend translate all routes like this:
/api/contacts/me
to:
/api/contacts/:id
where :id is the ID of the user who made the request, taken from the session. This can be done with a middleware to substitute the value for all routes at once, and then your normal controllers could use it like it was provided in the route to begin with.

How to protect my api call from CSRF attack

I am working on angular js app,and tried to make a simple login page and tried to request my server API for authenticate my login call.Here what and how i planned to do.
Note: I am assuming that server is responsible for validating my token and request.
Provide username password to server via API call.
On getting authenticated the server will generate a token for my App(through which i made a call).
I stored this in my browser's COOKIE.
This Cookie (auth token) will be further used by app to to make each and every HTTP call to API.
Now this approach is working fine for me,but I believe it is openly available for CSRF attack.
In order to avoid the CSRF attack from my browser,i provide APP id or (version id) to my code which also travel with cookie to the API for http call.
The idea behind using this version id or App id,is this can be treated as a signature of my code,ie request is coming from the signed (verified) app who has alloted token=cookie value.
i just want to know how better my approach is and how much secure it is for my basic app point of view and for my major (wide project) app.
Here i am trying to show via a rough diagram
apologies for this tiny view and bad handwriting of the diagram.
Backend frameworks like Laravel have this pretty built in: csrf-protection.
You can pass the token to Angular by using angular's constant function: $provide#constant.
So after you initialize your app you could say: angular.module('myApp').constant('<?php echo csrf_token(); ?>'); and Laravel would do the rest. If you would want to implement a technique like this yourself, you should look into Laravel's source code: https://github.com/laravel/framework/blob/a1dc78820d2dbf207dbdf0f7075f17f7021c4ee8/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php.
Adding App ID + Version ID to each request won't protect your system from a CSRF attack, unless these are in a custom header - and if they are you might as well just use X-Requested-With because any non standard header is protected going cross domain, provided you haven't enabled CORS with an open policy.
The reason that checking App ID + Version if set in the query string or POST data is that the attacker can readily gain this information to add the App ID + Version ID to their cross site requests. Another method that would work for you is the Double Submit Cookies technique. Generate a random 128 bit string using a CSPRNG and then set this as a cookie value (e.g. CSRFCookie). On each request to your API, also pass this value. e.g. in the query string: CSRFCookie=<generated value>. On the server side you simply check that the values match. An attacker does not know the cookie value, therefore they cannot add the same value to the query string.
This method does have some minor vulnerabilities, only really exploitable in a MITM scenario or if you do not control all subdomains. Short answer: Use HTTPS only for all your subdomains and implement HSTS.

How to authenticate requests to images in an angularJS app using an access_token

I have an angularJS application whose authentication system is made with an access_token and communicating with a backend server written in Go
Therefore to authenticate the user, I have to add the access_token to each request ?access_token=SomeTokenHere or via a header Access-Token: SomeTokenHere
It works great.
The issue is that my backend serves protected images, and I cannot put the access token in the image src for some security reasons(If the user copy/paste the link to someone else, the access_token would be given too ...)
What I'd like to do is to inject a header containing my access token, but since the request is made from the browser it doesn't possible.
This could probably be possible with a cookie, but I'd to avoid using a cookie especially because the angularApp and the backend are not on the same sub-domain.
Another idea would be to create a directive that would get the raw data, and set the data to the image. First I don't know if this is possible and is it a good idea for hundreds of images in the webpage ?
If you have any idea, I'd be glad to hear from you !
Thanks
It is typical problem, and fortunately it was already solved - for example on Amazon S3.
Solution idea is simple: instead of directly using secret key - you can generate signature with access policy, using that key.
There is good algorithm designed especially to generate signatures for this purpose - HMAC
You can have one secret key on your server and use it to sign every image URL before it would be sent to client, also you can add some additional policies like url expiration time...

How to securely set authorization header using angularJs?

It is common to authenticate to web services using an authorization header which contains a secret token. And since the security of this mechanism depends on the token to be secret care should be taken that this token is not leaked.
There are countless tutorials on the web which explains how such an authorization header can be set using angular and least the ones that I have actually read use an $http interceptor and now one discusses that the token is not leaked.
There are some public and some private APIs out there which can be talked to cross domain thanks to CORS. And obviously I do not want to send my internal authorization tokens on any of those requests.
Some other techniques come to mind such as setting the token manually only on each and every request, but that means lots of duplicate code. The $http server could be wrapped in an $authenticatedHttp service so that it is always appearent from the object used whether it is the authenticated service or the normal one. However the $http service has so many methods to be wrapped.
Is there a better solution?
UPDATE
From the answers I have the impression that my question was not understood. I try it with a more concrete example:
I have a private web page. People have to login with username/password and let's say for simplicity's sake that we use HTTP basic auth, so username/password are bas64 encoded and are transmitted on every request in the HTTP header "Authorization". So far there is no problem.
But there is this great&free weather widget. I can retrieve the current weather information in JSON format from https://myWhateverWeatherService.tld/weather.json. After the login to my private web service I also retrieve the weather information (CORS allows me to do this).
The problem is that even though myWhateverWeatherService.tld does not require any authentication at all, angular's $http service will still append the Authorization header. And I don't trust the guys at myWhateverWeatherService.tld. Maybe they just set up the service so they can steal Authorization token and do lot's of nasty stuff with them.
I need some reliable way to deal with that. I already thought about checking the url with some regex in the interceptor. This is possible, but it is also not to difficult to forget about a certain case that my regex will miss.
The token is always sent through the wire, I guess that is the most vulnerable part of it.
Since the token must always be present on the http header itself, the only way to make the request more secure is to encrypt the whole request, and for that you should use SSL.
If you are concerned about the safety of storing the token on the client machine, you can keep it only on the browser´s memory, without persisting it on a localstorage or something like that. So every time the user closes the browser and open it again, s/he must log in.

How to check for an HTTP status code of 401?

In one of the answers that I have received here, I encountered a problem of not knowing how to pass automatically through "Google App Engines" my ID and a password to a website, on which I am a registered user and have an account. A suggestion was given to me to "check for an HTTP status code of 401, "authorization required", and provide the kind of HTTP authorization (basic, digest, whatever) that the site is asking for". I don't know how to check for status code. Can anyone, please, tell me how to do it?
+++++++++++++++++++++++++++++++++
Additional Information:
If I use this way in Google App Engine (fetching the url of my eBay summary page):
from google.appengine.api import urlfetch
url = "http://my.ebay.com/ws/eBayISAPI.dll?MyEbay&gbh=1&CurrentPage=MyeBaySummary&ssPageName=STRK:ME:LNLK"
result = urlfetch.fetch(url)
if result.status_code == 200:
print "content-type: text/plain"
print
print result.status_code
I always get "200" instead of "401"
In ordinary Python code, I'd probably use the lower-level httplib, e.g.:
import httplib
domains = 'google.com gmail.com appspot.com'.split()
for domain in domains:
conn = httplib.HTTPConnection(domain)
conn.request('GET', '/')
resp = conn.getresponse()
print 'Code %r from %r' % (resp.status, domain)
this will show you such codes as 301 (moved permanently) and 302 (moved temporarily); higher level libraries such as urllib2 would handle such things "behind the scenes" for you, which is handy but makes it harder for you to take control with simplicity (you'd have to install your own "url opener" objects, etc).
In App Engine, you're probably better off using urlfetch, which returns a response object with a status_code attribute. If that attribute is 401, it means that you need to repeat the fetch with the appropriate kind of authorization information in the headers.
However, App Engine now also supports urllib2, so if you're comfortable with using this higher level of abstraction you could delegate the work to it. See here for a tutorial on how to delegate basic authentication to urllib2, and here for a more general tutorial on how basic authentication works (I believe that understanding what's going on at the lower layer of abstraction helps you even if you're using the higher layer!-).
Unless I don't understand fully your question, you can grab the return code from the Response Object using the status_code property.
First, you'll have to issue a fetch() to the URL you want to test.
Most user-oriented sites don't use HTTP authentication, preferring instead to use cookie-based authentication, with HTML forms for signin. If you want to duplicate this in your own code, you need to make an HTTP POST request to the login URL for the application in question, and capture the cookie that's sent back, including that in all your future requests to authenticate yourself. Without more details about the specific site you're trying to authenticate against, it's difficult to be more specific.
You are not getting 401 because that site is not returning 401 but 200 always. Usually type of coding we do for websites is return 200 with a page saying "Please login..blah blah", if site returned anything other then 200 browser will not display the funky error msg.
So in short as i mentioned in other question, you need to look into login page, see what params it uses e.g login=xxx, password=yyy, post it to that page and you will have to manage the cookies too, that is where library like twill etc come into picture.

Resources