Using Https Protocol for downloading data from Flickr - java

Since June 2014, all API keys just work via HTTPS only.Flickr deprecate non-SSL access to the API. There is another Post, but It's for 6 years ago which is before this event.
I know how to download data from Flickr, and I know it should work, but the problem is the library doesn't support Https.
I am trying to count the number of Images that have been shared by a user. I used getPeopleInterface().getPublicPhotos(userId,100,1) method.
but the problem is, it returns back Error 403 for URL!
I checked the Url in browser, and the Error is "SSL is required."
So I changed http to https in the URL and it worked. I do not know how I can change it in my code.
public class GetUsersPhotos {
public static void main(String[] args) throws Exception{
String key = "";
String secret = "";
String userId = "78069284#N00";
Transport t = new REST();
Flickr f = new Flickr(key, secret, t);
PhotoList list = f.getPeopleInterface().getPublicPhotos(userId,100,1);
System.out.println(list);
}
}

I solved my problem. The Flickrapi 1.2,doesn't support Https Protocol. What I did I downloaded Flickr4Java.jar which I checked and support Https, and then add the latest log4j jar file. then, it works.

Related

Java version of HttpWebRequest seDefaultCredentials = true;

I am currently working on authorizing the Qlik API proxy using Java. To do this I have to navigate through several redirects and then open a WebSocket. I have a version of C# that completes the task but need to port it over to java.
In Java, I am able to complete the redirects and obtain the session key for the WebSocket but I cannot seem to configure the NTLM credentials correctly for the WebSocket to accept them.
I am currently using apache HTTP client v 4.5. And nv-websocket-client for the WebSocket.
https://hc.apache.org/httpcomponents-client-4.5.x/index.html
https://github.com/TakahikoKawasaki/nv-websocket-client
In Java, I made a credentials object and set the NTLM credentials for the https request.
The issue is that in C# the call to the WebSocket seems to be automatically picking up the request.UseDefaultCredentials = true;.
My question is there a way to get this same functionality in Java or a library that supports the functions. Or if someone has used Java to complete this task any insight would be great.
I have tried configuring the headers for the WebSocket request to mirror the NTLM request, but I am not really sure where to go from here. Below is the c# set up I am looking to complete the same task.
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(URI);
request.Headers = headers;
request.Method = "GET";
request.Accept = "application/json";
request.Credentials = true;
System.Net.CredentialCache.DefaultNetworkCredentials;
request.UseDefaultCredentials = true;
request.AllowAutoRedirect = false;
request.CookieContainer = new CookieContainer();
I am currently receiving:
webSocketFrame(FIN=1,RSV1=0,RSV2=0,RSV3=0,Opcode=TEXT,Length=226,Payload="
{"jsonrpc":"2.0",
"method":"OnAuthenticationInformation",
"params":{"loginUri":baseurl+port"/internal_windows_authentication/?
targetId=ID returned here",
"mustAuthenticate":true}}")
The response I am looking for it:
webSocketFrame(FIN=1,RSV1=0,RSV2=0,RSV3=0,Opcode=TEXT,Length=226,Payload="
{"jsonrpc":"2.0",
"method":"OnAuthenticationInformation",
"params":{"loginUri":baseurl+port"/internal_windows_authentication/?
targetId=ID returned here ",
"mustAuthenticate":false}}") <---- the boolean flag is changed

when compiling No static field DEF_CONTENT_CHARSET of type Ljava/nio/charset/Charset; in class Lorg/apache/http/protocol/HTTP;

when using the nexmo api version 3.0+ (not using 4.0+ because require android version 8 api 27 ) and android version 6 api 23
i cannot send sms, as it is always giving the aforementioned error: No static field DEF_CONTENT_CHARSET of type Ljava/nio/charset/Charset; in class Lorg/apache/http/protocol/HTTP;
send sms code:
AuthMethod auth = new TokenAuthMethod(APIKey, APISecret);
NexmoClient client = new NexmoClient(auth);
TextMessage message = new TextMessage(fromRecipient, toRecipient, messageContent);
SmsSubmissionResult[] response = client.getSmsClient().submitMessage(message);
for (SmsSubmissionResult responseMessage : response) {
System.out.println(responseMessage);
}
I imported the following:
implementation 'org.apache.httpcomponents:httpclient:4.5+'
implementation 'org.apache.httpcomponents:httpcore:4.4+'
but it is still looking at the legacy httpclient instead of the imported ones
is there a way to force use the imported http client/core libraries instead of the legacy library?
It looks like you're trying to use the Nexmo Java Server SDK with Android. This is not something that is supported because it would require storing something like secrets and private keys inside of your application.
The recommended approach is to use the Server SDK on a server somewhere to secure this information, and then use your own authentication scheme to communicate with it via the Android app.

Google Translate API: Requests from this client application <empty> are blocked

I've been getting error 403 - Requests from this Android client application are blocked using paid Google Cloud Platform Translation API. Works great when restrictions are set to none.
There are a few threads around reporting similar issue, but none answered.
I've seen in some examples, there's a version which had .setApplicationName(), I think that might help, but I can't find which version would that be.
Code used is:`
private void translate(String textToTranslate, String targetLanguage, TranslateCallback callback) {
try {
TranslateOptions options = TranslateOptions.newBuilder()
.setApiKey( < api_key >)
.build();
Translate trService = options.getService();
Translation translation = trService.translate(textToTranslate,TranslateOption.targetLanguage(targetLanguage));
callback.onSuccess(translation.getTranslatedText());
}
catch(Exception e) {
callback.onFailure();
}
}`
from: https://medium.com/#amsanjeev/adding-translate-api-to-android-apps-788c5bca5521
Finally I found a way.
When setting up your API key restriction for android app, you specified the package name and SHA-1 certificate fingerprint. So when you send an request to Google, you must add these information in the header of each request.
connection.setRequestProperty("X-Android-Package", "com.example.awesomeapp");
String sign = "5D:5A:12:D3:......".toLowerCase(); //Your SHA1 key in lower cased.
connection.setRequestProperty("X-Android-Cert", sig);
A detailed answer can be found here.

Accessing kerberos secured WebHDFS without SPnego

I have a working application for managing HDFS using WebHDFS.
I need to be able to do this on a Kerberos secured cluster.
The problem is, that there is no library or extension to negotiate the ticket for my app, I only have a basic HTTP client.
Would it be possible to create a Java service which would handle the ticket exchange and once it gets the Service ticket to just pass it to the app for use in a HTTP request?
In other words, my app would ask the Java service to negotiate the tickets and it would return the Service ticket back to my app in a string or raw string and the app would just attach it to the HTTP request?
EDIT: Is there a similar elegant solution like #SamsonScharfrichter described for HTTPfs? (To my knowledge, it does not support delegation tokens)
EDIT2: Hi guys, I am still completly lost. Im trying to figure out the Hadoop-auth client without any luck. Could you please help me out again? I already spent hours reading upon it without luck.
The examples say to do this:
* // establishing an initial connection
*
* URL url = new URL("http://foo:8080/bar");
* AuthenticatedURL.Token token = new AuthenticatedURL.Token();
* AuthenticatedURL aUrl = new AuthenticatedURL();
* HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection();
* ....
* // use the 'conn' instance
* ....
Im lost already here. What initial connection do I need? How can
new AuthenticatedURL(url, token).openConnection();
take two parameters? there is no constructor for such a case. (im getting error because of this). Shouldnt a principal be somewhere specified? It is probably not going to be this easy.
URL url = new URL("http://<host>:14000/webhdfs/v1/?op=liststatus");
AuthenticatedURL.Token token = new AuthenticatedURL.Token();
HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection(url, token);
Using Java code plus the Hadoop Java API to open a Kerberized session, get the Delegation Token for the session, and pass that Token to the other app -- as suggested by #tellisnz -- has a drawback: the Java API requires quite a lot of dependencies (i.e. a lot of JARs, plus Hadoop native libraries). If you run you app on Windows, in particular, it will be a tough ride.
Another option is to use Java code plus WebHDFS to run a single SPNEGOed query and GET the Delegation Token, then pass it to the other app -- that option requires absolutely no Hadoop library on your server. The barebones version would be sthg like
URL urlGetToken = new URL("http://<host>:<port>/webhdfs/v1/?op=GETDELEGATIONTOKEN") ;
HttpURLConnection cnxGetToken =(HttpURLConnection) urlGetToken.openConnection() ;
BufferedReader httpMessage = new BufferedReader( new InputStreamReader(cnxGetToken.getInputStream()), 1024) ;
Pattern regexHasToken =Pattern.compile("urlString[\": ]+(.[^\" ]+)") ;
String httpMessageLine ;
while ( (httpMessageLine =httpMessage.readLine()) != null)
{ Matcher regexToken =regexHasToken.matcher(httpMessageLine) ;
if (regexToken.find())
{ System.out.println("Use that template: http://<Host>:<Port>/webhdfs/v1%AbsPath%?delegation=" +regexToken.group(1) +"&op=...") ; }
}
httpMessage.close() ;
That's what I use to access HDFS from a Windows Powershell script (or even an Excel macro). Caveat: with Windows you have to create your Kerberos TGT on the fly, by passing to the JVM a JAAS config pointing to the appropriate keytab file. But that caveat also applies to the Java API, anyway.
You could take a look at the hadoop-auth client and create a service which does the first connection, then you might be able to grab the 'Authorization' and 'X-Hadoop-Delegation-Token' headers and cookie from it and add it to your basic client's requests.
First you'll need to have either used kinit to authenticate your user for application before running. Otherwise, you're going to have to do a JAAS login for your user, this tutorial provides a pretty good overview on how to do that.
Then, to do the login to WebHDFS/HttpFS, we'll need to do something like:
URL url = new URL("http://youhost:8080/your-kerberised-resource");
AuthenticatedURL.Token token = new AuthenticatedURL.Token();
HttpURLConnection conn = new AuthenticatedURL().openConnection(url, token);
String authorizationTokenString = conn.getRequestProperty("Authorization");
String delegationToken = conn.getRequestProperty("X-Hadoop-Delegation-Token");
...
// do what you have to to get your basic client connection
...
myBasicClientConnection.setRequestProperty("Authorization", authorizationTokenString);
myBasicClientConnection.setRequestProperty("Cookie", "hadoop.auth=" + token.toString());
myBasicClientConnection.setRequestProperty("X-Hadoop-Delegation-Token", delegationToken);

Response code 401 when accesing rest based web services with correct credentials

I am getting Unauthorized error when accessing restful web services. My sample program looks like this.
public static void main(String[] args){
// Use apache commons-httpclient to create the request/response
HttpClient client = new HttpClient();
Credentials defaultcreds = new UsernamePasswordCredentials("aaa", "cdefg");
client.getState().setCredentials(AuthScope.ANY, defaultcreds);
GetMethod method = new GetMethod(
"http://localhost:8080/userService/usersByID/1234");
try {
client.executeMethod(method);
InputStream in = method.getResponseBodyAsStream();
// Use dom4j to parse the response and print nicely to the output stream
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
System.out.println(out.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
My credentials are correct. My web services will consume Basic Http Authentication.
I have doubt at scope of authentication.
client.getState().setCredentials(AuthScope.ANY, defaultcreds);
My credentials are correct.
Can any one help to resolve this issue.
Thanks.
First check your url via browser and verify ?? as mentioned here
Fixing 401 errors - general
Each Web Server manages user authentication in its own way. A security officer (e.g. a Web Master) at the site typically decides which users are allowed to access the URL. This person then uses Web server software to set up those users and their passwords. So if you need to access the URL (or you forgot your user ID or password), only the security officer at that site can help you. Refer any security issues direct to them.
If you think that the URL Web page *should* be accessible to all and sundry on the Internet, then a 401 message indicates a deeper problem. The first thing you can do is check your URL via a Web browser. This browser should be running on a computer to which you have never previously identified yourself in any way, and you should avoid authentication (passwords etc.) that you have used previously. Ideally all this should be done over a completely different Internet connection to any you have used before (e.g. a different ISP dial-up connection). In short, you are trying to get the same behaviour a total stranger would get if they surfed the Internet to the Web page.
If this type of browser check indicates no authority problems, then it is possible that the Web server (or surrounding systems) have been configured to disallow certain patterns of HTTP traffic. In other words, HTTP communication from a well-known Web browser is allowed, but automated communication from other systems is rejected with an 401 error code. This is unusual, but may indicate a very defensive security policy around the Web server.
Manual Fix
Hit the url from the browser and record the HTTP traffic (Headers,body)
Run the Java client code and record the HTTP traffic (Headers,body)
Analyze and fix the differences

Categories