You need to sign in to do that
Don't have an account?

Apex OAuth 2.0 Example
I'm an OAuth noob and strugging to get a login page to pop up where Apex is the client and GoToWebinar is the Service. How do I make the login screen pop up? Does it somehow magically take over the VF page via redirect or do I need some javascript to open a new window? Below is my attempted approach using HttpRequest:
My first attempt is something like this:
public class G2WButtonController{ public G2WButtonController(ApexPages.StandardController stdController){ } //Code that will run upon button click public void autoRun(){ callG2W(args); } public static void callG2W(String[] args) { String postURL='https://api.citrixonline.com/oauth/authorize?client_id=<myClientId>'; Http http = new Http(); HttpRequest req = new HttpRequest(); req.setEndpoint(postURL); req.setMethod('POST'); HttpResponse res = http.send(req); //Class to parse the results XmlStreamReader reader = res.getXmlStreamReader(); } }
VF
<apex:page standardController="G2W_Login__c" extensions="G2WButtonController" action="{!autoRun}"> <apex:pagemessages /> <apex:sectionHeader title="Auto-Running Apex Code"/> <apex:outputPanel > You tried calling Apex Code from a button. If you see this page, something went wrong. You should have been redirected back to the record you clicked the button from. </apex:outputPanel> </apex:page>
Once I get the login page to pop up, I'm assuming I would then parse the HttpResponse to get a param from the redirect URL- is that correct?
Any code samples others have would be greatly appreciated!
Update for anyone that finds this later. I learned I was approaching the problem wrong - I need to redirect to the URL with my aurthorization ID as a param and include a return URL that points to the VF page so that the controller can grab the param returned in the VF redirect URL and then make a server side post to get the access token, refresh token, and userId in the service provider.
I'm still not 100% sure how to securely store the access token, refresh token, and userId that the other app returns, but I'm guessing a custom setting might better than a custom object as its less discoverable. Not sure if sharing can be set to private on it though to minimize prying eyes.
All Answers
Update for anyone that finds this later. I learned I was approaching the problem wrong - I need to redirect to the URL with my aurthorization ID as a param and include a return URL that points to the VF page so that the controller can grab the param returned in the VF redirect URL and then make a server side post to get the access token, refresh token, and userId in the service provider.
I'm still not 100% sure how to securely store the access token, refresh token, and userId that the other app returns, but I'm guessing a custom setting might better than a custom object as its less discoverable. Not sure if sharing can be set to private on it though to minimize prying eyes.
I'm having the same problem as you! Would you be able to shed some light on the code to get the pop up and redirect back to my page?
I punted on the idea of a pop up and instead just had my VF page button redirect that page to the 3rd party site, which then returns to the same VF page after authorization.
No need to use the same VF page for the button & redirect, but I wanted to show the confirmation on the same page.
I'm not experienced enough to know how to have a pop up talk back to another browser tab, so this approach was easier for me and provides a decent customer experience too.
Gotcha, thanks!
Wondering if you can shed some light on how to capture the code from the redirect after the user enter his credentials, when the user is redirect back to the VF page?
Cheers!
http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#StartTopic=Content/apex_pages_pagereference.htm?SearchType=Stem
Hi John,
Thanks for the snippet. I used a javascript button to call the authorization page, but don't know how to detect the redirect back to my VF page. Is there some kind of listener or event trigger out there that does this? Or is my approach incorrect?
Thanks so much!
The flow for the service provider I'm authenticating to requries the redirect URL as part of the initial request.
I don't have the syntax at hand, but it was something like:
https://api.<serviceprovider>.com/oauth/authenticate?clientId=<myAppsId>&redirect=<full URL for my vf page>
They then add the param to my redirect url after the user authorizes access.
Hi John,
That's the exact syntax I have too. After the user enters his credentials and clicks on 'Allow Access' then the user is redirected back to <full URL for my vf page>
The problem is that how do I detect that the user is done and the redirect has happened, and execute the rest of my code? The pageRef works if I'm calling the the authorization page within a class. Here is the sequence of events
1. User clicks on Javascript button on VF Page
2. Javascript sends user to authorization page on the same page (no popups)
3. User enters credentials and clicks on allow access
4. user is redirected back to <full URL for my vf page> with code= XXXXX tagged to the end of the URL
5. Detect redirect (how do you do this?)
6. Execute the rest of the code
I'm stuck on step 5. If the approach is correct.
Thanks again!
You don't "detect the redirect", you have the redirct point to a VF page and have an autorun method grab any param in the URL. If the URL contains the "success code", then you know it succeeded and you got there as a result of the redirect.
Bingo. Thanks John!
Hi,
I am also trying for the same thing. But i am getting bad request error. Could you please post the sample code if you dont mind.. Please help me..
Thanks,
Lakshmi
Something like this:
Hi John,
i got the error while i am using your code..
I got the error at this line someOtherClass.accessTokenURL(responseKey);
And i have used the code like
public class gotowebinaroauth
{
public string res1{set;get;}
private string session;
string code{set;get;}
public boolean frame{set;get;}
public gotowebinaroauth()
{
frame=false;
session = userInfo.getSessionId();
system.debug(session +'sss==');
code=apexpages.currentpage().getparameters().get('code');
if(code!=null)
second();
system.debug(code+'code===');
}
public pagereference detail()
//public void detail()
{
frame=true;
Http h = new Http();
HttpRequest req = new HttpRequest();
final string username = 'username here';
final string password = 'welcome1';
Blob headerValue = Blob.valueOf(username + ':' + password);
//String authorizationHeader = 'BASIC ' +EncodingUtil.base64Encode(headerValue);
String authorizationHeader = 'OAuth' +EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization',authorizationHeader);
//req.setHeader('Authorization', 'OAuth ' );
//req.setHeader('Host','https://api.citrixonline.com/oauth/authorize?client_id=7ce8c52e2cbe09c32a9ddc09f1894ac3');
//req.setHeader('Host','https://api.citrixonline.com/oauth/authorize?client_id=7ce8c52e2cbe09c32a9ddc09f1894ac3&redirect_uri=http://www.dskvap.com/');
//req.setHeader('Host','https://api.citrixonline.com/oauth/authorize?client_id=be77d883448f4e585805ab7873c40cda&redirect_uri=http://www.dskvap.com');
req.setHeader('Host','https://api.citrixonline.com/oauth/authorize?client_id=87f1f7a08282efd61bb0bd9f045ce1fd&redirect_uri=https://c.ap1.visual.force.com/apex/gotowebinaroauth');
req.setHeader('Connection','keep-alive');
req.setHeader('Content-Type', 'application/json;charset=UTF-8');
req.setMethod('GET');
//req.setEndpoint('https://api.citrixonline.com/oauth/authorize?client_id=7ce8c52e2cbe09c32a9ddc09f1894ac3');
//req.setEndpoint('https://api.citrixonline.com/oauth/authorize?client_id=7ce8c52e2cbe09c32a9ddc09f1894ac3&redirect_uri=http://www.dskvap.com/');
//req.setEndpoint('https://api.citrixonline.com/oauth/authorize?client_id=be77d883448f4e585805ab7873c40cda&redirect_uri=http://www.dskvap.com');
req.setEndpoint('https://api.citrixonline.com/oauth/authorize?client_id=87f1f7a08282efd61bb0bd9f045ce1fd&redirect_uri=https://c.ap1.visual.force.com/apex/gotowebinaroauth');
HttpResponse res = h.send(req);
res1=res.getbody();
system.debug('********'+res.getbody());
pagereference p=new pagereference('https://api.citrixonline.com/oauth/authorize?client_id=87f1f7a08282efd61bb0bd9f045ce1fd&redirect_uri=https://c.ap1.visual.force.com/apex/gotowebinaroauth');
return p;
}
string s1;
string s2;
public void second()
{
s1=apexpages.currentpage().getparameters().get('code');
s2 = s1.remove('=');
system.debug(s2+'s2==');
Http h = new Http();
HttpRequest req = new HttpRequest();
final string username = 'username here;
final string password = 'welcome1';
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +EncodingUtil.base64Encode(headerValue);
//String authorizationHeader = 'OAuth' +EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization',authorizationHeader);
req.setHeader('Authorization', 'OAuth ' );
req.setHeader('Host','https://api.citrixonline.com/oauth/access_token?grant_type=authorization_code&code='+s2+'&client_id=87f1f7a08282efd61bb0bd9f045ce1fd');
req.setHeader('Connection','keep-alive');
req.setHeader('Content-Type', 'application/json;charset=UTF-8');
req.setMethod('POST');
req.setEndpoint('https://api.citrixonline.com/oauth/access_token?grant_type=authorization_code&code='+s2+'&client_id=87f1f7a08282efd61bb0bd9f045ce1fd');
HttpResponse res = h.send(req);
res1=res.getbody();
system.debug('********'+res.getbody());
}
}
<apex:page controller="gotowebinaroauth">
<apex:form >
<apex:commandButton value="Get Details" action="{!detail}"/><br/>
<apex:outputText value="{!res1}"></apex:outputText>
</apex:form>
</apex:page>
I am getting the error as, Bad request error. I have tried a lot but not getting.. Can you help me please..
Thanks,
Lakshmi
Looks like you are trying to pass the username/pw, which kinda defeats the whole purpose of oAuth (to protect those).
The flow I recommend is supposed to be like this:
1) User clicks on VF tab
2) My Autorun method in the VF controller fires on page load. If there's no param (there wouldn't be at this point), then nothing happens
3) User clicks button on VF page. This is the URL of your app's oAuth flow. For GoToWebinar, I'd guess this is passing a new PageRef with a param for your app's Id
4) User should see a username/pw login screen & logs in
5) User approves the app
6) If you set up the app properly, it should redirect to your VF page with some parameters for success. In my example, the param was called "code"
7) On VF page load, the same AutoRun method fires again, checking for this param. Since it exists, it then sends that param to another method, which makes an API call to get the access token & refresh token.
Hi John,
I am using a trigger that calls a class which prepares the JSON to be sent to the Google Calendar API v3.
I'm trying to bypass the OAuth 2.0 pop-up that comes, maybe by using a static key or using the 'Connected App' option.
Please guide which is the best way and how to proceed further.
Thanks,
Kartik
Kartik - can you email me? I'd like to better understand what you're desired experience is here. I'm just getting up to speed on how connected apps work relative to oAuth but hopefully can point you in the right direction.
We're looking at implementing a Google contact import (safe harbor) using a similar library and the flow we'll use is something like:
I might be missing a step in #5 to exchange the auth code for an access token but don't have time to check right now.
btw-email is jkucera at salesforce dot com.