I'm trying to get an OAuth implementation running on a servlet for Twitter. I'm having trouble with redirecting the user to the Twitter authentication page. When I get the callback, it's returned to a servlet but the session is different since the request comes from Twitter and not my webapp.
I tried using encodeRedirectURL to get the session to persist to the outside site but that doesn't work. Need help!
You have to add the session ID as jsessionid fragment of callback URL. Twitter has to callback to http://example.com/callbackservlet;jsessionid=1E6FEC0D14D044541DD84D2D013D29ED (note: the jsessionid value is here just an example).
The HttpServletResponse#encodeRedirectURL() (and encodeURL()) won't encode the URL when the client already supports cookies. You need to hard-encode it yourself.
String url = "http://example.com/callbackservlet";
String encodedURL = url + ";jsessionid=" + request.getSession().getId();
Related
So we've a spring-boot based oauth2 server.
One of our applications relying on this server tries to initiate an auth request using the following url:
https://oauth2server/oauth/authorize?response_type=code&grant_type=authorization_code&client_id=myClient&redirect_uri=http%3A%2F%2Fapplicationserver%2Flogin%3Fparameter%3Dvalue
The user enters credentials, approves the app, and is redirected back to the application-server via the redirect_uri with a code:
http://applicationserver/login?parameter=value&code=tokenCode
When the application-server then calls the oauth2 resource api (oath/token) it gets RedirectMismatchException("Redirect URI mismatch.") because the approved redirect doesn't contain the query string parameters, rather only http://applicationserver/login
How can we set a certain url prefix to be an approved redirect uri while ignoring query string parameters? or are we doing something inherently wrong?
Thanks!!
If I understand it correctly your intention is to send data with the initial authorize request which should be returned when redirecting back to the application.
A library I am using currently provides the feature that an additional state can be stored together with the nonce in the state parameter like:
state = nonce + nonceStateSeparator + customState;
The state parameter is described as:
An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.
I have a legacy Java 1.6 running localhost with Tomcat 7 application using JSP pages, a frameset with frames, javascript, but no framework like Struts. I pass an object to display in the page from the servlet using the request or session and that works fine.
However, I made some changes recently and now I can't retrieve that same object back from the session or request. It had been working fine previously, so I'm not sure what is broken, but I can't even send a string value back from the JSP's back to the servlet.
I created a new stripped down JSP and I can't get anything back from that either using the request or session. It does the same thing when I push the code our Tomcat 6 web server. Using the debugger, I see the objects populated in the session, but then lost later when a new session is created each time as in using this simple code to get the sessionid:
System.out.println("The session id is: " + session.getId());
The session id is: EB431C19B41957B2BB2EFC3DBAF32241
The session id is: C9CBD30E84D5C93DF6114C1412AE5523
I then see this in firebug under the Header, response headers:
Set-Cookie JSESSIONID=C9CBD30E84D5C93DF6114C1412AE5523; Path=/Name omitted here/; HttpOnly,
so I know cookies are set. I also removed jquery and I"m stripping down the jsp code as much as possible, but that doesn't seem to be the issue.
I'm using:
HttpSession session = request.getSession(true); but using false didn't matter.
session.setAttribute("ObjNameList", objNameList);
The context.xml has cookies set to true and we do use response.sendRedirect, but only if an error is thrown as in: response.sendRedirect("Error.jsp"); There is no place in the code with session invalidate either.
All I'm doing from the jsp is sending a form back using something like:
document.formName.submit(); which works fine. Using this code to try and set a simple string in the session doesn't work either:
session.setAttribute("somevalue","someValue");
Gives me null in the servlet here:
String val = (String) session.getAttribute("somevalue");
Any ideas as to what could be causing this?
Resultion:
It turned out to be an issue with the url, a typo actually, as BalusC mentioned, so the path for the session cookies didn't match between the jsp and the servlet.
Doublecheck if the request URL to that servlet matches the session cookie domain and path. If it doesn't match, then the browser simply won't send the session cookie back along with the request and the server will think that there's no means of an established session and will therefore simply create a new one.
You can check cookies in the HTTP traffic monitor of browser's web developer toolset (press F12 in Chrome/Firefox23+/IE9+ and open "Network" tab). When a new session starts, the server must have returned a response with Set-Cookie header with therein the cookie value and path (and implicitly domain). When the browser sends a subsequent request on the same domain and path, then it must have passed that cookie back via Cookie request header.
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
We have the following situation:
JSESSIONID is being sent by both cookies and URL, but because of a Adobe Flash BUG, they are different (actually, the cookie JSESSIONID is wrong).
What we would like to do is to use the URL JSESSIONID instead of the one sent in the cookies. In other words, when I execute request.getSession(), it should return the HttpSession associated to the ID in the URL and not in the cookie.
We looked into Tomcat7 source code and, in fact, Tomcat first parses the URL, searching for an identifier. Then it overrides it with cookies SESSIONID if they are present. Here is the code snipped in CoyoteAdapter.java (tomcat 7.0.26):
String sessionID = null;
if (request.getServletContext().getEffectiveSessionTrackingModes()
.contains(SessionTrackingMode.URL)) {
// Get the session ID if there was one
sessionID = request.getPathParameter(
SessionConfig.getSessionUriParamName(
request.getContext()));
if (sessionID != null) {
request.setRequestedSessionId(sessionID);
request.setRequestedSessionURL(true);
}
}
// Look for session ID in cookies and SSL session
parseSessionCookiesId(req, request);
parseSessionSslId(request);
We could disable cookies JSESSIONID at all, but we can't because we use it for all URLs in the website. We'd like to disable cookies for JUST THIS SPECIFIC URL.
Is it possible? Is there any other idea or workaround to solve this problem?
You could implement a custom servlet filter that would replace request, response and session objects with your own wrappers. The wrappers then can behave differently based on the URL, e.g. delegate or not to the original session instance. Though you won't be able to access session data for some other id, without changing Tomcat code.
I'm starting to use facebook Graph API and I'm going to retrieve an access token with some simple HTTP requests via java.
Following https://developers.facebook.com/docs/authentication/
I created a new app but I don't have a domain so
I make an HTTP request to
www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&
redirect_uri=https://www.facebook.com/connect/login_success.html
for a server-side flow, and I suppose to get redirect to a success page with a code in the URL. Then I would use this code make another HTTP request to
graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
and finally get my access token.
I used both java.net.HttpURLConnection and org.apache.http.HttpResponse,
but, in both cases, executing the first call I get as response the HTML of a Facebook login page.
If I use this HTML to create a webpage and then I simply click on the Login button (without inserting username and password) I get the success page with the code!
In the HTML the field submit of the button Login is empty and I can't retrieve redirect URLs... I can just read an alternate link in the <meta> tag which generate an auth_token (what is it? It is very different wrt an normal access_token...).
So what I ask is:
it is possible to detect the hidden redirect in some way just
using java.net.HttpURLConnection or
org.apache.http.HttpResponse?
if yes, how is the mechanism? Is it related to the auth_token?
if no, is it possible with other libraries? (I used also restfb,
but they seems to require an access token inserted "by hand" as an
arg, and I also saw facebook-java-api but it seems old).
Also if I'm logged in Facebook, executing the first HTTP call via Java I get as response the HTML of a Facebook login page.
Using HTML to create a webpage and then I simply click on the Login button (without inserting username and password) I get the success.htm page with the code parameter in the URL.
If I use the original URL directly in my browser I can directly obtain the success.htm page without passages in the middle.
So I suppose the problem is in the management of cookies: in Java (executed in Eclipse) I cannot access my browser's cookies.
I tried to redirect to use a Servlet but I get the error about the domain:
ServletURL is not a Facebook domain or a "site URL" registered for my app (actually I did't set a site URL for my app... and that's the problem core).
In any case here
http://developers.facebook.com/docs/authentication/
in the section App types > Desktop apps they say:
[...] After the user authorizes your app [I allowed everything], we
redirect the user back to the redirect_uri with the access token in
the URI fragment: [...]
Detect this redirect and then read the access token out of the URI
using whatever mechanisms provided by your framework of choice. [...]
So I think that it is still possible to detect this redirect via Java. How?
If you do not have a domain yet I recommend you using localhost as a domain. That way you can test it on your local web server / local app.
Using HttpURLConnection works fine.
This is how we do it.
Redirect to:
"https://graph.facebook.com/oauth/authorize?" +
"client_id=" + clientId + "&" +
"redirect_uri=" + URLEncoder.encode(returnUrl, "utf-8")
// After redirect to the return url do the following:
//Make a http request to
"https://graph.facebook.com/oauth/access_token?client_id=" +
"client_id=" + clientId + "&" +
"redirect_uri=" + URLEncoder.encode(returnUrl, "utf-8") + "&"+
"client_secret=" + clientSecret + "&"+
"code=" + request.getParameter("code");
This will return an access token which you can query facebook with
I have a problem with redirection, in my work I have to make a connection to a URL that automatically go to another URL at this point it takes the credential (username and password) and redirect to a URL that contains a parameter which need me. How can I take this parameter?
To be precise, I have to do this:
Embed a Web browser with the URL https://graph.facebook.com/oauth/authorize with your client_id and the type set to user_agent. Since your application is embedding a small window, you can trigger a compact "popup" version of the authorization dialog with the display parameter:
graph.facebook.com/oauth/authorize?
client_id=...&
redirect_uri=www.facebook.com/connect/login_success.html&
type=user_agent&
display=popup
After the user authorizes your application, we redirect the user back to www.facebook.com/connect/login_success.html with the access token in the URL fragment: www.facebook.com/connect/login_success.html#access_token=...&expires_in=... Intercept the redirect above and read the access token out of the URL. Use the access token to fetch data from the Graph API on behalf of the user:
graph.facebook.com/me?access_token=....
I need access_token.
you can use apache http components httpclient to do this,
it will automatically follow redirects
HttpClient client=new HttpClient();
GetMethod get=new GetMethod("graph.facebook.com/oauth/authorize?client_id=...& redirect_uri=www.facebook.com/connect/login_success.html&type=user_agent&display=popup");
int status=client.exectueMethod(get);
Then you will have the information you need in the Location header of the response which you can access by using:
String location=get.getResponseHeader("location").getValue();
and parse the location-header for the url fragment you want.
hope that helped