I am writing a client for Restful web services.
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();
}
}
I am getting unauthorized error 401. When I checked the server logs. I found the following.
ERROR httpclient.HttpMethodDirector - Credentials cannot be used for NTLM authentication: org.apache.commons.httpclient.UsernamePasswordCredentials
So, I understood that I need to use NTLM authentication for this.
Can some one tell me how to modify this to do NTLM authentication.
Thanks in Advance.
Please check the below links
http://hc.apache.org/httpclient-3.x/authentication.html#NTLM
http://davenport.sourceforge.net/ntlm.html
Instead of setCredentials try using setProxyCredentials.
client.getState().setProxyCredentials(AuthScope.ANY, defaultcreds);
Related
I would like to test my web service using Junit. Once we missed the public modifier and it failed. So, to avoid such issue in the earlier stage we would like to write Junit test cases to test the web service connection.
I tried this but did not work.
String url = "http://localhost:port/webservice/path";
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = new HttpGet( url );
request.setHeader("username", "user1");
HttpResponse httpResponse =
HttpClientBuilder.create().build().execute(request);
HttpResponse response = client.execute(request);
httpResponse.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
while ((line = rd.readLine()) != null) {
result.append(line);
}
My web service will be like this
#Path("/path")
public interface WebServiceTest
{
//list of services
}
I should get to know whether my call is success or failure through Junit test case.
How to implement it? Any other suggestions other than Junit but It should be through Java (No Mockito)?
EDIT: I need this for both SOAP and REST web services.
Try to use RestAssured. Using a method like this and pass the appropriate values.
public static ResponseBody callAPI(String host, String body, String path, String method, Map<String,String> headers){
RequestSpecBuilder requestSpecBuilder = new RequestSpecBuilder();
requestSpecBuilder.addHeaders(headers);
requestSpecBuilder.setBody(body);
requestSpecBuilder.setBaseUri(host);
RequestSpecification requetSpecification = requestSpecBuilder.build();
requestSpecBuilder.setContentType(ContentType.JSON);
Response rs = null;
if(method.equals("DELETE")){
rs = RestAssured.given(requetSpecification).when().log().all().delete(path);
}else if(method.equals("POST")){
rs = RestAssured.given(requetSpecification).when().log().all().post(path);
}
return rs.getBody();
}
I have the following code:
public class SendRequest {
public static void main(String[] args) throws ClientProtocolException, IOException {
String url = "http://backoffice.xyz";
HttpHost proxy = new HttpHost("proxy.proxy", 8080, "http");
HttpClient client = HttpClientBuilder.create().setProxy(proxy).build();
HttpGet request = new HttpGet(url);
//request.addHeader("User-Agent", "USER-AGENT");
HttpResponse response = client.execute(request);
System.out.println("Response Code: " + response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while((line = rd.readLine()) != null){
result.append(line);
}
System.out.println(result.toString());
}
}
This is returning a 407 Unauthorized Access/Cache Access Denied Error. What code do i need to include so i can authenticate through the proxy?
Does your proxy require username/password based authentication? If so, try implementing java.net.Authenticator. I guess you will need to set useSystemProperties
Authenticator.setDefault(new Authenticator(){
PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(username, password);
}
});
You might need to add setDefaultCredentialsProvider(CredentialsProvider credentialsProvider) to the HTTPClientBuilder and use SystemDefaultCredentialsProvider instance for that.
1.Can you check your proxy ?? I'm not sure if proxy.proxy is correct.
Your rest of the code seems fine.
2.And also make sure you are updating httpcore version to 4.4 or above. And also you can update httpcore to latest version.
3.You could check the authentication of your proxy as #Goutham mentioned
Hope this helps!!
I have a question regarding getting Refresh Token for Google Analytics using JWT.
Please refer the below sample code which is working fine and i am able to get the Analytics object, using which i am able to access the Analytics data.
GoogleCredential credentialGA = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("$#$##$#$#$#developer.gserviceaccount.com")
.setServiceAccountScopes(Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY))
.setServiceAccountPrivateKeyFromP12File(new File("$#$#$%$%$%$-privatekey.p12"))
.build();
this.analytics = new Analytics.Builder(httpTransport, JSON_FACTORY, credentialGA).setApplicationName("Demo App").build();
If i make a call to credentialGA.getAccessToken() it returns me a string. But making a call to credentialGA.getRefreshToken() it always returns me null.
Now as per the saying if i have to use this Analytics object for further calls, i need to have refresh token using which i can again create GoogleCredential object to get Analytics object.
So i created a JWT, after following the steps mentioned in https://developers.google.com/accounts/docs/OAuth2ServiceAccount. This JWT is then to be used for making refresh token call.
Example shared on this link explains how to make it possible through servlet/jsp/http.
https://code.google.com/p/gwdg-java/source/browse/src/java/com/google/iapsample/?r=a52c4e72381b1fc959053e3a1fc8c585ae2d7112
Is there any example code which may explain to achieve the same task of Refresh token call using JWT using Java Standalone app.
Thanks in advance.
regards,
Prathamesh
Code to generate JWT :
private final static Charset UTF8_CHARSET = Charset.forName("UTF-8");
private static KeyStore myStore = null;
private static FileInputStream in_cert = null;
public static void main(String[] args) {
PrivateKey privateKey = null;
try {
in_cert = new FileInputStream(
"D://Google Analytics//ClientLogin//Analytics//%#$%#$%$^%^%$&^%&$-privatekey.p12");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
myStore = KeyStore.getInstance("PKCS12");
myStore.load(in_cert, "notasecret".toCharArray());
Enumeration<String> aliases = myStore.aliases();
String alias = "";
Enumeration objEnumeration = myStore.aliases();
while (objEnumeration.hasMoreElements() == true) {
alias = (String) objEnumeration.nextElement();
privateKey = (PrivateKey) myStore.getKey(alias,
"notasecret".toCharArray());
if(privateKey != null){
System.out.println("PRIVATE KEY:" + privateKey.toString());
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
JsonObject header = new JsonObject();
header.addProperty("alg", "RS256");
header.addProperty("typ", "JWT");
String headerStr = header.toString();
JsonObject claim = new JsonObject();
claim.addProperty("iss", "%^#%#^%$%#developer.gserviceaccount.com");
claim.addProperty("scope", "https://www.googleapis.com/auth/devstorage.readonly");
claim.addProperty("aud", "https://accounts.google.com/o/oauth2/token");
claim.addProperty("exp", "1384497516");
claim.addProperty("iat", "1384597516");
String claimStr = claim.toString();
try {
byte[] headerArr = headerStr.getBytes(UTF8_CHARSET);
System.out.println(Base64.encodeBase64String(headerArr));
byte[] claimArr = claimStr.getBytes(UTF8_CHARSET);
System.out.println(Base64.encodeBase64String(claimArr));
String inputStr = Base64.encodeBase64String(headerArr) + "." + Base64.encodeBase64String(claimArr);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(inputStr.getBytes(UTF8_CHARSET));
} catch (Exception e) {
e.printStackTrace();
}
This JWT string is then copied and used in another programmer to request for Refresh token as shown below:
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("<link i have posted in the comment>");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("grant_type",
"urn:ietf:params:oauth:grant-type:jwt-bearer"));
nameValuePairs.add(new BasicNameValuePair("assertion",
"<JWT Calculated earlier>"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
if (line.startsWith("Auth=")) {
String key = line.substring(5);
}
}
} catch (IOException e) {
e.printStackTrace();
}
What you actually need for a successful API call is an access token. For a service account, you get an access token by signing a JWT with a private key and sending it to accounts.google.com.
It looks like your code above should do this fine.
A refresh token is a different kettle of fish. This is something that Google will supply your application with after an end-user has authorized your application for access to their data. Similar to the private key above it can be used to get an access token that can then be used for subsequent API calls.
So simply put, for a service account use-case (which is what the code snippet shows) you should never need to see a refresh token at all. What specifically are you looking to do?
I think you can check the validity of the accessToken by calling the
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={accessToken}
endpoint and make the JWT again and get the accessToken.
I'm trying to send a POST request to the Chrome sync service which is located at https://clients4.google.com.
I'm using that short piece of code to send a request that I captured before with the help of BURP Suite and saved to a file. It's what Chrome sends when connecting to the sync service.
That code opens an SSLSocket, connects to the Chrome server and sends the contents of that file (see below):
private void sendRequest() {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) sslsocketfactory.createSocket("clients4.google.com", 443);
socket.startHandshake();
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
sendMessage(out, new File("request.bin"));
readResponse(in);
out.close();
in.close();
}
private void sendMessage(BufferedWriter out, File request) throws IOException {
List<String> result = getContents(request);
for (String line : result) {
out.write(line + "\r\n");
}
out.write("\r\n");
out.flush();
}
private void readResponse(BufferedReader in) throws IOException {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
private List getContents(File file) throws IOException {
List<String> contents = new ArrayList<String>();
BufferedReader input = new BufferedReader(new FileReader(file));
String line;
while ((line = input.readLine()) != null) {
contents.add(line);
}
input.close();
return contents;
}
The request.bin file looks like this (it's a plaintext request without SSL):
POST /chrome-sync/command/?client=Google+Chrome&client_id={VALID_CLIENT_ID} HTTP/1.1
Host: clients4.google.com
Connection: keep-alive
Content-Length: 1730
Authorization: GoogleLogin auth={MY_VALID_AUTH_DATA}
Content-Type: application/octet-stream
User-Agent: Chrome WIN 23.0.1271.97 (171054)
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
{binary data}
Now this request fails as the server returns HTTP/1.0 404 Not Found.
But why does this happen?
It's the exact same request Chrome sends, isn't it? What am I missing here?
Answering my own question here: The problem was with the encoding. The binary data in the request body got slightly modified and that caused the Google server to respond with errorcode 404 (which is pretty confusing).
Now that I'm using proper encoding everything works fine.
if you input chrome://sync/ in your chrome's addr bar, you will see the server url is:
https://clients4.google.com/chrome-sync/dev
some more information you can find in this link:
http://code.google.com/p/chromium/issues/detail?id=90811
And /command? needs authentication. I found some info may be helpful for you. Check the comments of this issue:
http://code.google.com/p/chromium/issues/detail?id=108186
hope it helps
66305
HI,
I want to invoke a Servlet from the client side, as a Onclick event on a Button in java programming language.
I read somewhere through anchor tag we can call a servlet, but i did not figure out the solution or Syntax properly.
Anyone please me.
Thanks,
sekhar
Typically you use a RemoteService to communicate with a server. To do that, you create an interface that extends RemoteService and an implementation on the server that implements that interface and extends RemoteServiceServlet. All that is described in more detail here. If you need to make a call to some servlet that isn't a remote service servlet, you can use RequestBuilder to send an HTTP request to that servlet's URL.
An Anchor is basically just a normal HTML <a> tag which could link to the URL of a servlet.
You have to manually create one httpClient & call GET/POST method.
Below is sample code using POST method:
//---
HttpClient client = new HttpClient();
BufferedReader br = null;
PostMethod method = new PostMethod("http://someUrl.com");
method.addParameter("p", "\"parameter\"");
int statusCode = client.executeMethod(method);
if(statusCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.out.println("Not Supported");
method.getResponseBodyAsString();
} else {
br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
String readLine;
while(((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
//---