I crawled google a lot to find some documentation on the subject but did not find anything.
I am trying to use a kerberos ticket to access a secured server but i get a 401 error.
What i do is add a header with the base64 encoded token before calling the web service
HessianConnection conn = ...
conn.addHeader("Authorization", "Negotiate " + token);
...
conn.sendRequest();
I know that hessian supports Basic auth (HessianProxyFactory => setUser/PWD/BasicAuth), but i m not sure about Spnego/Negotiate.
Note that we managed to setup spnego with cxf in another project (It has HttpAuthSupplierImpl), but this one uses hessian.
Question : is it possible or i am wasting my time ?
Thanks
Actually i checked HTTP traffic server side with wireshark, it seems that headers are correctly sent with this code. So this works and this question can be closed. The ticket is however not correctly recognized but this is another problem ...
Related
https://www.cbz.com Link when pasted in IE or chrome Doesn't ask for authentication but when I write java code hitting the same URL I get Error 401.
I am in client's network and i don't know his credentials but I still want to hit the URL and generate the token.
Note :I do not provide Username Password of the client in httpurlconnection and want the functionality like the browsers(i.e without asking for uid/pwd).
Anything shared by anyone will be much appreciated!!!
You need to pass the crediantials, either use single signon using providers like SiteMinder or an LDAP authentication.
I am getting FileNotFoundException when making GET call to REST API. Here HTTP status code I get is 403.
For POST call I get IOException : No authentication challenges found, whereas I pass Authorization header. Here I get HTTP status code 401.
Look at my already asked question to see the code and logcat screen shot for POST call.
Below I am attaching logcat screen shot for GET call :
Note :
1) I have tried using Authenticator.
2) Tried different base64 flags such as NO_WRAP, URL_SAFE, DEFAULT.
3) My simple call to www.google.com works.
4) When I log urlConnection.getErrorStream(), last line in image is printed. I don't understand what is that and what does it mean. I have specified Content-type to application/json in header.
UPDATE : I tried using Burp and found that headers "Accept", "Content-type" were different. I used the same as in iOS app. But still it does not work.
Things to note :
1) It always throws an Exception on the line in = urlConnection.getInputStream();.
2) I logged few things and according to it, content-length is 114, which is not null. content-type is application/json; charser=utf-8.
There's a difference between your HTTP traffic for iOS and for Android. This is guaranteed, otherwise you'd get identical behaviour from the server. The difference is probably in HTTP header(s) &/or parameter(s).
This is very difficult to debug remotely via SO Q&A - E.g. we don't know what headers & parameters your iOS client is successfully using nor how your server is configured & programmed.
How to diagnose the problem & correct yourself:
Trace your working HTTP traffic: iOS client <-> server
Trace your non-working HTTP traffic: Android client <-> server
Compare (2) and (3). For the most thorough comparison, save each HTTP request and response message as a separate file for (2) and (3), then diff the corresponding files.
Recommended HTTP tracing tools:
Fiddler2 (windows only) See also Documentation
Burp (JVM-based: windows, linux, OSX, etc) See also Getting Started
WebScarab (JVM-based: windows, linux, OSX, etc) See also Getting Started
UPDATE
Seems you have the same problem for both GET and POST: the server is configured for BASIC authentication, but the client is not following the authentication protocol correctly. I think it just shows as a slightly different sympton in the two cases: for GET it says 'resource not found' (because you're not authenticated) and for POST the resource is given by you, but the server says you're not authorized to change the resource on the server. I suggest you've done enough (good!) debugging of request contents and now you should stop and focus on getting authentication working.
Send you GET/POST request to the server without Authorization header
Allow the server to prompt you for authentication with a 401 response with an WWW-Authenticate header containing a challenge string (e.g. WWW-Authenticate: Basic realm="Protected" see RFC 2617 HTTP Basic Authentication and Digest Authentication)
Now send an additional GET request to server that (either without/with the original request contents), but includes the Authentication header, with Base 64 encoded username:password (Authorization: Basic ZnJhbms6ZmllZGxlcg==)
I solved my problem and it is something I never tried to focus on while solving the problem.
I need not pass Authorization header. The thing is that there are 2 credentials come into the picture. one is server's authorization and second is credentials for login API. In my app, user creates an account and login to it. To authenticate the user I pass credentials to server and server authenticate it.
So when user enters correct credentials then response received is correct. And, in case of wrong credentials, my server passes a error message You are not authorized person, which I want to display to user(as in my iOS app). So the problem is here that HTTP status code (in case of wrong credentals) is 401 and that is why I don't receive the message sent by the server (and receive No authentication challenges found message).
The reason why I don't receive server message is that HttpUrlConnection don't give server response when HTTP status code is >= 400.
The only option to get error details in case status code 400 and above is to use getErrorStream() method and using that I was receiving No authentication challenges found message.
Finally, either I had to handle each status code, that is equal and above 400, at client side or I can use HttpClient, instead of HttpUrlConnection. And now I am moving to HttpClient.
I had a similar problem, and solved by passing the authenticated session cookie. Not sure if that is possible in your situation.
AuthUser="foobar"
AuthPass="password"
URL targetUrl = new URL("http://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
String authStr = Base64Variants.MIME_NO_LINEFEEDS.encode((AuthUser+":"+AuthPass).getBytes());
connection.addRequestProperty("Authorization", "Basic "+authStr);
InputStream inputStream= connection.getInputStream();
I just run something like this and it worked perfectly for me. Just make sure you use Base64Variants.MIME_NO_LINEFEEDS and you should be able to create a proper authentication header. If that doesn't work, then you might have some problem on the server side.
I'm working on creating a simple method that send SOAP request to EWS and it seems everything is OK. But when I run it I get error:
java.net.ProtocolException: Server
redirected too many times (20)
Any ideas why I get this when I try to connect to https://my.exchange.server/ews/Services.wsdl ?
Note: my.exchange.server is just a cover for my real URL
Make sure to enable Basic Authentication on EWS, sorry that's on the server side :).
I am using EWS Java Api http://archive.msdn.microsoft.com/ewsjavaapi and it works fine even cross domains:
ExchangeService service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials("Administrator#yourdomain.com", "Password",
"yourdomain.com");
service.setCredentials(credentials);
service.setUrl(new URI("http://yourserver/EWS/Exchange.asmx"));
service.setPreAuthenticate(true);
BTW, I am also successfully reaching it with plain SOAP using SoapUI, but the key factor is enabled Basic Authentication, and URL is "http://yourserver/EWS/Exchange.asmx"
Good luck,
Boris
Herndon, VA
I'm trying to consume a restful webservice in java using the Apache Wink framework through my school web proxy requiring authentification
ClientConfig clientConfig = new ClientConfig();
clientConfig.proxyHost("proxy.school.com");
clientConfig.proxyPort(3128);
//nothing to set username and password :(
RestClient client = new RestClient(clientConfig);
Resource resource = client.resource("http://vimeo.com/api/v2/artist/videos.xml");
String response = resource.accept("text/plain").get(String.class);
I've also tried to use the BasicAuthSecurityHandler but it seems to be used to authenticate directly to a web server, not the web proxy
BasicAuthSecurityHandler basicAuthHandler = new BasicAuthSecurityHandler();
basicAuthHandler.setUserName("username");
basicAuthHandler.setPassword("password");
config.handlers(basicAuthHandler);
It still fail with a HTTP 407 error code : Proxy Authentication Required.
I've googled the best I could, nothing came up better to consume a webservice from a Java client through a web proxy, if someone has another idea, feel free to respond
Ok that was pretty hard but I found it ! I logged the HTTP requests that were being made from my browser with Fiddler and found out that the Proxy-Connection and Proxy-Authorization were what I was looking for after reading extensive documentation like RFC 2616 about HTTP/1.1
So I copy-pasted the values that were being sent into my java code :
resource.header("Proxy-Connection", "Keep-Alive");
resource.header("Proxy-Authorization", "Basic encodedString");
where encodedString is what is being sent by my browser : username:password base64 encoded
And it now works perfectly :)
This issue was raised as [1] and has since been resolved with the addition of a ProxyAuthSecurityHandler available to Apache Wink client developers.
[1]: https://issues.apache.org/jira/browse/WINK-292 Apache Wink JIRA issue WINK-292
I get the following error from following piece of code. I am trying to login to Google sites service through GAE apps.
"The page you requested is invalid. "
String authenticationUrl = userService.isUserLoggedIn()
? userService.createLogoutURL(MainServlet.MAIN_URL)
: userService.createLoginURL(MainServlet.MAIN_URL+"?close=1");
googleData.setAuthenticationUrl(authenticationUrl);
The complete url for login
https://www.google.com/a/example.com/ServiceLogin?service=ah&passive=true&continue=http://myapp.appspot.com/_ah/login?continue=http://myapp.appspot.com/main%3Fclose%3D1<mpl=ga&ahname=Myapp+Google+Sites&sig=7cbc9f7c9e6ca443ed49f7ce9465e775
I think that you may have misunderstood the use and purpose of createLoginURL. This method is intended to provide a URL that allows someone to log in to your application and your application alone. It does not provide a means to log in to other Google services such as Sites.
It is possible to have your application log on to and access Sites or any other secured web application, but Google AppEngine does not provide a canned means of doing so. You will need to write the code to do it yourself.
Generally, what will happen is that you will request a URL and the response will have an HTTP status code of 302 with the URL of the login page located in the Location header field. You would then send a request to that page which should come back with a 200 response and somewhere inside the body of the response would be a username and password field that you would need to provide and POST back. If the credentials were valid, the server might then return an authentication cookie which you would pass on each subsequent request.
If you are versed at all in Python, you can see an example of how this works in some code from my AppEngine MVC framework project. Look at this file:
http://code.google.com/p/gae-mvc-engine/source/browse/trunk/MVCTests.py and check out the ActiontestCase.run_action method. It handles making a request to an AppEngine application that requires authentication. It is not yet terribly-well commented -- and for that I aplogize -- but I hope that it will provide a useful example. If, indeed, I have understood the nature of your problem correctly.