In Evernote, "state" parameter in authorization url is not getting passed in callback - evernote

I'm using scribe for oauth. In authorization url, I'm passing 'state' parameter with a token to identify the user during callback request.
authorizationUrl = EVERNOTE_SERVICE.getAuthorizationUrl(requestTokenObject.getToken());
log.info("Auth url : " + authorizationUrl);
redirect(authorizationUrl + "&state=" + token);
But in the callback, I'm not receiving the "state" parameter. I'm only receiving "oauth_token" and "oauth_verifier" in the callback. I'm expecting this has to work and everyone else should be doing this already. What am I missing?

Evernote currently uses OAuth1.0, it looks like the state parameter was added in OAuth2. OAuth1.0 does not have a state parameter.

I was able to get the a state parameter back in the callback, by adding it to the callback url as query parameter.
The url for oauth_callback looks something like this then: http://localhost?state={state}

Related

returnUrl drops second querystring parameter

I am using MVC 5. The problem is that after SSO redirects back to the app after authentication the login method returnUrl drops the applicaitonId querystring parameter. Please help!
Here is the flow.
The app redirects unauthorized users to a login method, preserving the original request in the returnUrl.
The original request is
http://localhost:25451/shared/download?documentGroup=133&applicationId=3153
the returnUrl is
/shared/download?documentGroup=133&applicationId=3153
The app redirects to a SSO CAS server, sending along the HttpUtility.Encode returnUrl as a parameter along with login Url both part of the service parameters.
https://{redacted}/cas/login?service=http://localhost:25451/account/login%3freturnUrl%3d%2fshared%2fdownload%3fdocumentGroup%3d133%26applicationId%3d3153
After authentication, the CAS server appends the authorized ticket and redirects back to the service URL. This is what fiddler shows.
http://localhost:25451/account/login?returnUrl=/shared/download?documentGroup=133&applicationId=3153&ticket={redacted}
Here is the issue. The returnuRL in the login method is simply
/shared/download?documentGroup=133.
The returnUrl no longer has the applicationId.
Interestingly enough, the line works just fine.
var ticket = Request.QueryString.Get("ticket");
I have tried to encode the whole serviceUrl and tried to encode just the returnUrl(see below) but I get the same missing ApplicationId issue.
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
var ticket = Request.QueryString.Get("ticket");
if (!string.IsNullOrEmpty(ticket))
{
//verify the ticket...
return RedirectToLocal(returnUrl);
}
var serviceUrl = Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host + (Request.Url.IsDefaultPort ? "" : ":" + Request.Url.Port) + "/account/login" + "?returnUrl=" + HttpUtility.UrlEncode(returnUrl);
var authenCasUrl = string.Format("{0}login?service={1}", "https://{redacted}/", serviceUrl);
return Redirect(authenCasUrl);
}
Since this site will be actually called by your URL, I don't think they just throw away parts of it.
Lets try something here since I have encountered a similar problem with parameter in url strings in combination with asp.NET.
First, lets get the unedited URL from your Request:
string UneditedUrl = Request.RawUrl;
Since we are not needing anything before the ? mark, we shorten it a little bit:
string QueryString = (UneditedUrl.IndexOf('?') < UneditedUrl.Length - 1) ? UneditedUrl.Substring(UneditedUrl.IndexOf('?') + 1) : String.Empty;
This line also includes the possibility on neither having a ? mark or parameters and will return an empty string if so. Just for good measure, we don't want any exceptions here. Here you can check QueryString if it has both or more of your parameters you entered.
If there are not complete here, its not your code at fault. Something will already work on your URL before you do, probably your host then. Maybe check the settings of your IIS.
If your parameters are correctly in the edited QueryString, you can continue getting them by following this:
I learned that there is a way to let your framework do the job of parsing parameters into name/value collections. So lets give it a go:
NameValueCollection ParaCollection = HttpUtility.ParseQueryString(QueryString);
You can now check you params and their values by either using an index like ParaCollection[0] or ParaCollection["documentGroup"].
EDIT:
I've found the question which brought me to the conclusion of using Request.RawUrl. Since this may not be the answer, it will maybe help a little bit more to understand that Request.RawUrl is the actual URL the user called and not the one the server executes: RawURL vs URL
I have no experience with asp or SSO, but you may need to also HttpUtility.UrlEncode the value of the serviceUrl variable?
var authenCasUrl = string.Format("{0}login?service={1}", "https://{redacted}/", HttpUtility.UrlEncode(serviceUrl));
Since the service parameter is decoded by the CAS once, and then the value of returnUrl gets decoded by your server.
var returnUrl = "/shared/download?documentGroup=133&applicationId=3153";
var serviceUrl = "http://localhost:25451/account/login?returnUrl=" + HttpUtility.UrlEncode(returnUrl);
var casUrl = "https://{redacted}/cas/login?service=" + HttpUtility.UrlEncode(serviceUrl);
Which gives:
serviceUrl = http://localhost:25451/account/login?returnUrl=%2Fshared%2Fdownload%3FdocumentGroup%3D133%26applicationId%3D3153
casUrl = https://{redacted}/cas/login?service=http%3A%2F%2Flocalhost%3A25451%2Faccount%2Flogin%3FreturnUrl%3D%252Fshared%252Fdownload%253FdocumentGroup%253D133%2526applicationId%253D3153
Explanation attempt:
You make a HTTP request to the CAS server. It's implementation splits the query parameters and decodes each value (and possibly key). One of which is the service parameter and is now (after decoding) a valid URL.
The CAS server makes a HTTP request with the URL from the service parameter (to your server) with the ticket appended.
You split the query parameters and decode each value (and possibly key).
If you only encoded the returnUrl once, your serviceUrl will look like what you showed in your third point:
http://localhost:25451/account/login?returnUrl=/shared/download?documentGroup=133&applicationId=3153&ticket={redacted}
How does the algorithm splitting the query string differentiate between a ? or & in the serviceUrl and the ones in the returnUrl?
How should it know that ticket does not belong to the returnUrl?
As you can see in my code above, you are not encoding the returnUrl twice.
You are putting one URL in the parameters of another URL and then you put that URL in the parameters of a third URL.
You need to call UrlEncode for each value (and possibly key) when you put together a query. It does not matter whether that value is a URL, JSON, or arbitrary user input.

Define parameters as param request instad of endpoint url in fasthttprouter

I am using golangĀ“s fasthttprouter and have followed the examples and defined a router like this:
router.GET("/customer/account/detail/:accountId", myHandler.customerAccountDetailHandler)
Then I call to my service as http://locahost:9296/customer/account/detail/2
But I realised that I do not want to have the parameters as part of the endpoint , I rather prefer to use normal parameters by calling my service like this:
http://locahost:9296/customer/account/detail?accountId=2&sort=1
Is it possible to be done with fasthttprouter? How?
Thanks in advance
J
The query parameter should be accessible from the request context.
You should have a handler that takes a *fasthttp.RequestCtx argument. This RequestCtx can access the URI and the query params on that URI. That should look something like this:
ctx.URI().QueryArgs().Peek("accountId")
You'll have to update your handler to use this query parameter instead of the route param you were previously using. The same would also apply for the sort param.
Also, your router would have to be updated to route /customer/account/detail to your updated handler (i.e. you'll want to remove /:accountId from your route).
Your questions is similar to this one:
Get a request parameter key-value in fasthttp
You can retrieve the parameters of the request in this way:
token = string(ctx.FormValue("token"))
Have a look at my complete response here
https://stackoverflow.com/a/57740178/9361998
Documentation: https://godoc.org/github.com/valyala/fasthttp#RequestCtx.FormValue

How to get # value in query string from a URL coming from an API, not the current request

I get a returned url from using facebook api:
http://www.example.com/#access_token=BAAGgUj7asdasdasdasda4z3cBAFD5ZAyTOMIxtBpjIHsNwLfZC6L9gZAIdSIt3bKP96rg7yAlplMBDA9ZCndAKS9a7m4oRmRmJAxSdCueefweWJrlq3vQv3XaGqTOLofEMjJIVNCYZD&expires_in=0
But i am not sure how to get the token value? As its not in query string or Request.url
Any help?
You can't, assuming this is passed in on the current request, as anything after the # is never sent to the server.
You can capture it in JavaScript and use AJAX to send it to the server, but this will be on a different request.
If you mean you have this URL not from the current request, you can use the Uri class to parse a full URL and get the fragment:
var fragment = new Uri(theUri).Fragment;
var token = fragment.Split(new [] {'&','='}, StringSplitOptions.None)[1];
You can use HttpUtility.ParseQueryString to parse the URL then you can get the value by name e.g.
NameValueCollection query = HttpUtility.ParseQueryString(querystring);
string token = query["token"];
Check this Retrieving Anchor Link In URL for ASP.Net
you cannot get it from the server side, you will need to take if from client side first then pass it to the server in a hidden field or something similar
You have to look for "%23", because "#" is url-encoded to "%23"
reference:
http://www.w3schools.com/tags/ref_urlencode.asp
But you have to know also, that anchors are not available on server side!

HTTP request parameters are not available by request.getAttribute()

I am sending an url parameter to servlet using the following jQuery piece:
$.getJSON("http://localhost:8080/JsoupPrj/JasonGen?url=" + url, function(data) {
$("#content").html(data);
});
On the server side, the servlet gets the parameter, for that I coded as below:
String url = (String) request.getAttribute("url");
But it is not working, can you tell me where I am doing wrong? I believe I am not passing the parameter properly to the servlet. The servlet triggers each time through the JavaScript, but it is not seeing the parameters passed from the browser.
Here,
String url = (String) request.getAttribute("url");
you're trying to get a request parameter as a request attribute instead of as a request parameter. This will obviously not do what you want.
You need to get a request parameter as a request parameter, not as a request attribute.
String url = request.getParameter("url");
Unrelated to the concrete problem: you don't seem to be URL-encoding the parameter at all before sending. This will possibly cause other problems, unrelated to this one, when the url contains special characters. Look at the JS encodeURIComponent() function, or the data argument of the $.getJSON() function. See for more hints also How to use Servlets and Ajax?

How to perform an HTTP POST request in ASP?

How would I go about creating a HTTP request with POST data in classic asp (not .net) ?
You can try something like this:
Set ServerXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
ServerXmlHttp.open "POST", "http://www.example.com/page.asp"
ServerXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
ServerXmlHttp.setRequestHeader "Content-Length", Len(PostData)
ServerXmlHttp.send PostData
If ServerXmlHttp.status = 200 Then
TextResponse = ServerXmlHttp.responseText
XMLResponse = ServerXmlHttp.responseXML
StreamResponse = ServerXmlHttp.responseStream
Else
' Handle missing response or other errors here
End If
Set ServerXmlHttp = Nothing
where PostData is the data you want to post (eg name-value pairs, XML document or whatever).
You'll need to set the correct version of MSXML2.ServerXMLHTTP to match what you have installed.
The open method takes five arguments, of which only the first two are required:
ServerXmlHttp.open Method, URL, Async, User, Password
Method: "GET" or "POST"
URL: the URL you want to post to
Async: the default is False (the call doesn't return immediately) - set to True for an asynchronous call
User: the user name required for authentication
Password: the password required for authentication
When the call returns, the status property holds the HTTP status. A value of 200 means OK - 404 means not found, 500 means server error etc. (See http://en.wikipedia.org/wiki/List_of_HTTP_status_codes for other values.)
You can get the response as text (responseText property), XML (responseXML property) or a stream (responseStream property).
You must use one of the existing xmlhttp server objects directly or you could use a library which makes life a bit easier by abstracting the low level stuff away.
Check ajaxed implementation of fetching an URL
Disadvantage: You need to configure the library in order to make it work. Not sure if this is necessary for your project.

Resources