I (want to) use CommunityService.updateCommunityLogo(file, communityUuid) to set a logo for a freshly programmatically created community.
The call runs though without error, but the logo is not changed.
When I look into the apache.http.wire logs, it shows following conversation:
>> PUT /communities/service/html/image?communityUuid=6e700c5d-082c-497f-8657-d516a01f62e7 HTTP/1.1 (without data so far)
<< HTTP/1.1 100 Continue
>> (binary data of image)
apache.http.wire(78): << "HTTP/1.1 100 Continue[EOL]"
apache.http.wire(78): << "[EOL]"
impl.conn.DefaultClientConnection(229): Receiving response: HTTP/1.1 100 Continue
apache.http.headers(232): << HTTP/1.1 100 Continue
apache.http.wire(78): << "HTTP/1.1 200 OK[EOL]"
impl.conn.DefaultClientConnection(229): Receiving response: HTTP/1.1 200 OK
apache.http.headers(232): << HTTP/1.1 200 OK
apache.http.wire(64): << "<script language="JavaScript1.2">[\n]"
apache.http.wire(64): << " document.cookie = "CommunitiesReqURL=" + location.href + "; expires=" +[\n]"
apache.http.wire(64): << " new Date(new Date().getTime() + 365*24*60*60*1000).toGMTString() + "; path=/communities";[\n]"
apache.http.wire(64): << " location.href = "/communities/service/html/login";[\n]"
apache.http.wire(64): << "</script>[\n]"
I have skipped some details like Date, Content fields etc. from header and wire, but this is what basically happens.
This in turn is part of a request processing from inside a web application which should automatically do some things on a Connections instance. Thus, as a result, this web application will present the answer to the original user request to the user as a web page. This in turn contains a frame with the community which was changed here -- but after this step the user is forced to login anew on Connections (although the LTPA token is "fresh") in full-window mode.
Thus I suspect that calling CommunityService.updateCommunityLogo(file, communityUuid) forces re-authentication and destroys/invalidates the current LTPA token or authenticated session.
What is happening here?
What can I do about it?
Remarks:
I have no access to any Connections logs actually.
The Connections instance is v4.5 and directly accessed using BasicAuth in IBM SBT, but uses form-based auth in the browser.
The SBT version is 1.0.2.20140527-1807, included using maven 3.0.5, deployed on tomcat 7.0.53 on Java 7.
it's actually most likely related to the 100 continue for that API
I wrote an article on it http://bastide.org/2014/06/19/expect-100/
For J2EE Apps, navigate to your managed-beans.xml. Locate the Endpoint you want to disable it for, add a managed-property.
forceDisableExpectedContinue
true
some sample code I wrote for this...
public static void main(String[] args){
URL url;
try {
String imageUrl = "https://servername.com/communities/service/html/image?communityUuid=1e244250-6740-4949-aaac-682707a47099";
String imageType = "image/png";
String folder = "/Users/paulbastide/Desktop/";
String fileName = "demo.png";
File file = new File(folder + fileName);
long fileLength = 0l;
String userAgent = "Apache-HttpClient/4.3.3 (java 1.5)";
String auth = "Basic =";
url = new URL(imageUrl);
HttpsURLConnection httpCon = (HttpsURLConnection) url.openConnection();
httpCon.setDoOutput(true);
//https://code.google.com/p/misc-utils/wiki/JavaHttpsUrl
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
} };
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance( "SSL" );
sslContext.init( null, trustAllCerts, new java.security.SecureRandom() );
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
httpCon.setSSLSocketFactory( sslSocketFactory );
/**
* adds the cookies
*/
httpCon.setRequestProperty("Cookie", "");
// Responds to two operations PUT and DELETE
httpCon.setRequestMethod("PUT");
httpCon.setRequestProperty("Content-Type", imageType );
httpCon.setRequestProperty("slug", fileName);
httpCon.setRequestProperty("Content-Length", "" + fileLength );
httpCon.setRequestProperty("Content-Encoding", "binary");
httpCon.setRequestProperty("User-Agent", userAgent);
httpCon.setRequestProperty("Authorization", auth);
byte[] fileBytes = FileUtils.readFileToByteArray( file);
DataOutputStream out = new DataOutputStream(
httpCon.getOutputStream());
out.write(fileBytes);
out.close();
httpCon.getInputStream();
System.out.println("The Response Code is " + httpCon.getResponseCode());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
IBM SBT SDK 1.0.3 solves this problem: Tests with the same application code and 1.0.2 / 1.0.3 revealed that 1.0.2 is buggy here, but in 1.0.3 this issue is fixed.
Additionally however the server side has undergone an upgrade from IC 4.5 to IC 5.0, but with the 1.0.2 IBM SBT SDK also IC5 did not accept the logo. Thus it might be both: IC45 -> IC5 AND SBT 1.0.2 -> 1.0.3.
Related
I am trying to read outlook emails within my organization using javax mail, but I keep getting the error - "javax.mail.AuthenticationFailedException: Logon failure: unknown user name or bad password."
One thing to note is that there is a Single Sign On required while logging into outlook. So you have to enter the same credentials (emailID/password) twice.
The following is my code -
public static void main(String[] args) {
String host = "pop.outlook.com";
String mailStoreType = "pop3";
String username = "firstname.lastname#companyName.com";
String password = "password";
check(host, mailStoreType, username, password);
}
public static void check(String host, String mailStoreType, String user, String password)
{
try {
//create properties field
Properties props = new Properties();
props.setProperty("mail.pop3.ssl.enable", "true");
props.setProperty("mail.pop3.auth.plain.disable", "true");
props.put("mail.pop3.host", host);
props.put("mail.pop3.port", "995");
props.setProperty("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(props);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore(mailStoreType);
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
Logger.logConsoleMessage("messages.length---" + messages.length);
for (int i = 0, n = messages.length; i < n; i++) {
Message message = messages[i];
Logger.logConsoleMessage("---------------------------------");
Logger.logConsoleMessage("Email Number " + (i + 1));
Logger.logConsoleMessage("Subject: " + message.getSubject());
Logger.logConsoleMessage("From: " + message.getFrom()[0]);
Logger.logConsoleMessage("Text: " + message.getContent().toString());
}
//close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
After tweaking the above code a little, i am able to access a gmail account, which leads me to believe that the error above is because of the extra authentication required by SSO. Has anyone encountered this ever ? Any inputs would be greatly appreciated, Thanks!
In my new project, I am going to include google recaptcha.
my question is fairly simple even if we do client side validation that user is not a robot even though it is suggested to do server side validation.
I want to know why it is necessary to do server side validation for google recaptcha? how does it add the extra layer of security? and how to do in spring boot with spring security?
Server side validation is MUST !! reCAPTCHA is designed in a way that client side just generates the 'g-captcha-response' which along with secret key (stored at server-side) is sent to https://www.google.com/recaptcha/api/siteverify for validation. The response is a JSON which states sucesss true or false and it is further pushed to client side. Validating only at the client side is technically possible, but it defeats the purpose. Moreover, you may get CORS (Cross-Origin Resource Sharing) policy error in console if you do only client side validation. I can share steps to do simple java based server side validation in servlet. Let me know if you need that.
Here is the code. Few points to be noted:
The parameter userResponse = request.getParameter("recaptchaResponse") is the way by which i am getting the 'g-recaptcha-response' generated by the user when he clicked reCAPTCHA widget on UI. On your javascript, capture the value of field 'g-recaptcha-response' and pass it appended to request. Then in servlet, we can get it from request.getParameter.
Sample code:
var recaptchaResponse = document.getElementById("g-recaptcha-response").value;
//alert("g-recaptcha-response= "+recaptchaResponse);
if (recaptchaResponse.length > 0)
{
var xmlhttp1;
if (window.XMLHttpRequest)
{
xmlhttp1=new XMLHttpRequest();
}
else
{
xmlhttp1=new ActiveXObject("Microsoft.XMLHTTP");
}
var query1 = "?recaptchaResponse=" + recaptchaResponse;
xmlhttp1.open("POST","captchaVerificationServlet" + query1, false);
xmlhttp1.send(null);
var resp1 = xmlhttp1.responseText;
alert("resp1= "+resp1);
if(resp1=='matched'){
return true;
}
else{
alert("resp1 did not match");
return false;
}
}
else{
alert("error: recaptcha response is blank");
return false;
}
For simplicity i am checking presence of "success:true" in returned JSON response. As you know, returned JSON contains two parameters : success and error-codes. You may use a JSONReader to read and parse JSON and obtain all parameters fully. Sample code will be like
JsonReader rdr = Json.createReader(your_inputstream);
JsonObject jsonObject = rdr.readObject();
Needless to say, remove all alerts and sop statements in production!
public class CaptchaVerificationServlet extends HttpServlet {
private static final String sec = YOUR_SECRET_KEY;
public void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userResponse = request.getParameter("recaptchaResponse");
response.setCharacterEncoding("UTF-8");
System.out.println("userResponse= "+userResponse);
//verify user response with Google ReCaptcha API
String ipAddress = request.getRemoteAddr(); //get client's ip address
System.out.println("ipAddress= "+ipAddress);
try{
String s = validateCaptcha(sec, userResponse, ipAddress);
Boolean success = (s.contains("\"success\": true"));
if(success)
response.getWriter().write("matched");
}
catch(Exception ioe){
ioe.printStackTrace();
ioe.printStackTrace(response.getWriter());
}
}
private String validateCaptcha(String secret, String response, String remoteip) throws IOException
{
URLConnection connection = null;
InputStream is = null;
String output = "";
String proxyHost = "YOUR_PROXY_NAME";
int proxyPort = 80; //proxy server port, generally 80 or 443 (confirm from sys-admin)
SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort);
Proxy httpProxy = new Proxy(Proxy.Type.HTTP, addr);
String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
String password = "changeit";
System.setProperty("javax.net.ssl.trustStore",filename);
System.setProperty("javax.net.ssl.trustAnchors",filename);
System.setProperty("javax.net.ssl.trustStorePassword",password);
String charset = Charset.forName("UTF-8").name();
String url = "https://www.google.com/recaptcha/api/siteverify";
try {
String query = String.format("secret=%s&response=%s&remoteip=%s",
URLEncoder.encode(secret, charset),
URLEncoder.encode(response, charset),
URLEncoder.encode(remoteip, charset));
URL fullURL = new URL(url + "?" + query);
connection = fullURL.openConnection(httpProxy);
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0");
is = connection.getInputStream();
System.out.println("connection InputStream");
BufferedReader reader = null;
String responseXXX = "";
reader = new BufferedReader(new InputStreamReader(is));
responseXXX = reader.readLine();
while (responseXXX!=null) {
output+= responseXXX;
responseXXX = reader.readLine();
}
System.out.println("Output: " + output);
}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
//cannot do anything here
}
}
}
return output;
}
}
I am trying to write a simple JAVA REST Client through which I want to PUT/GET elasticsearch document information.
PUT is working fine, my json data got added into index.
But the problem is GET, Response Code is 200, but it is not returning any data.
Can anyone please help.
public static String httpGet(String resturl){
String output = null;
try {
URL url = new URL(resturl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
//System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
I am calling as
RestClient.httpGet("http://localhost:9200/gabsindex/employee/_search")
You println call is currently commented out. If you uncomment it, you'll get the response from the server on one single line, something like
{"took":50,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":7056,"max_score":1.0,"hits":[...]}}
If you are trying to follow this approach educationally, this can be ok. Remember, nonetheless, that there are a number of libraries that can be used exactly for this use. You should check out the clients page.
I cannot connect to my server using HttpClient when Posting, it works fine with get, and works fine with post to other servers (such as google), any ideas?
I am NOT using android.
The server responds fine when accessing it by browser.
As it is probably a server config issue, i do not have full access to the server, it is a hosted webserver, however i have access to the cpanel
private static String GetURL(String inUrl, String post) {
String inputLine = "";
try {
if (!inUrl.contains("http")) {
throw new Exception("Invalid URL");
} else {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(inUrl);
httpPost.addHeader("Accept-Charset", "UTF-8");
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
//create post
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("req", post));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(httpPost);
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
inputLine = in.readLine();
in.close();
}
}catch (Exception ex) {
inputLine = "" + Comms.ERROR_COULD_NOT_REACH_SERVER;
Log.writeLog("Could Not Reach Server: \"" + inUrl + "\"");
ex.printStackTrace();
}
return inputLine;
}
org.apache.http.NoHttpResponseException: The target server failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:95)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:715)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:520)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at Comms.GetURL(Comms.java:87)
at Comms.sendCommand(Comms.java:64)
at Comms.main(Comms.java:43)
I'm creating an Android app that should do the following;
Use a form on a https (SSL!) page to login and receive a cookie
Issue httpGET actions to get html
parse that html and show it in a view, list or something.
I've been fooling around with Jsoup, httpUnit and HTMLUnit for quite some time now, but I'm running in to several problems;
A. Login is fine, works.. (I get the website's welcome page) but then, when I issue a GET statement (and include the cookie), I am redirected to the login form. So the response html is not what I expected. (might have something to do with a keepalivestrategy?)
B. InputBuffers are too small to receive entire HTML pages and set them up for parsing.
NB : I do not have control over the webserver
I'm totally new at this, so a tutorial or code snippets would be helpful.
For instance, this is what I use to login to the website :
public int checkLogin() throws Exception {
ArrayList<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("userid", getUsername()));
data.add(new BasicNameValuePair("password", getPassword()));
data.add(new BasicNameValuePair("submit_login", "Logmein"));
Log.d(TAG, "Cookie name : " + getCookieName());
Log.d(TAG, "Cookie cont : " + getCookie());
HttpPost request = new HttpPost(BASE_URL);
request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
request.getParams().setParameter("http.protocol.handle-redirects",false);
request.setEntity(new UrlEncodedFormEntity(data, "UTF-8"));
HttpResponse response;
httpsclient.getCookieStore().clear();
List<Cookie> cookies = httpsclient.getCookieStore().getCookies();
Log.d(TAG, "Number of Cookies pre-login : " + cookies.size());
response = httpsclient.execute(request);
cookies = httpsclient.getCookieStore().getCookies();
Log.d(TAG, "Number of Cookies post-login : " + cookies.size());
String html = "";
// Problem : buffer is too small!
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
str.append(line);
}
in.close();
html = str.toString();
Document doc = Jsoup.parse(html);
Log.v(TAG, "Ik heb nu dit : " + doc.toString());
if (cookies.size() > 0){
storeCookie(cookies.get(0).getName(), cookies.get(0).getValue());
return MensaMobileActivity.REQUEST_SUCCESS;
} else {
return MensaMobileActivity.REQUEST_ERROR;
}
}
You don't handle the SSL certificate at all, that's at least a part of the problem. I struggled starting to learn this recently as well. This block of code will grab the SSL cert from the webpage you're accessing.
try {
URL url = new URL(YOUR_WEBPAGE_HERE);
HttpsURLConnection connect = (HttpsURLConnection)url.openConnection();
connect.connect();
Certificate[] certs = connect.getServerCertificates();
if (certs.length > 0) {
cert = new File("YOUR_PATH_TO_THE_FILE");
//write the certificate obtained to the cert file.
OutputStream os = new FileOutputStream(cert);
os.write(certs[0].getEncoded());
return true;
}
}
catch (SSLPeerUnverifiedException e) {
e.printStackTrace();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (CertificateEncodingException e) {
e.printStackTrace();
}