Client giving error when invoking a secured web service - axis2

I have written a client that invokes webservice. My client is:
String publisherEPR = "https://abc:8280/services/ProviderPublication";
protected void publicationOpenSession(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Inside publicationOpenSession");
date = new Date();
namespace = "http://www.openoandm.org/xml/ISBM/";
fac = OMAbstractFactory.getOMFactory();
OMNamespace ns = fac.createOMNamespace(namespace, "ns1");
OMElement result = null;
channelURI = request.getParameter("TxtPublisher1ChannelURI");
textfield = request.getParameter("TxtAreaServicePublisherLog");
String finalChannelURI = "";
int count = 0;
try {
if (channelURI != null && (channelURI.indexOf(".") > -1)) {
System.out.println("Inside If Checking Channel URI");
String[] tempChannelURI = channelURI.split("\\.");
for (count = 0; count < tempChannelURI.length - 1; count++) {
finalChannelURI = finalChannelURI + tempChannelURI[count];
if (count < tempChannelURI.length - 2) {
finalChannelURI = finalChannelURI + ".";
}
}
System.out.println("Inside If Checking Channel URI : " + finalChannelURI);
}
System.out.println("OpenPublicationSession" + finalChannelURI);
System.out.println(publisherEPR);
OMElement OpenPublicationSessionElement = fac.createOMElement("OpenPublicationSession", ns);
OMElement ChannelURIElement = fac.createOMElement("ChannelURI", ns);
ChannelURIElement.setText(finalChannelURI);
OpenPublicationSessionElement.addChild(ChannelURIElement);
String webinfFolder = request.getSession().getServletContext().getRealPath("/WEB-INF");
ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
webinfFolder, webinfFolder + "/conf/axis2.xml");
Options options = new Options();
ServiceClient client = new ServiceClient(ctx, null);
EndpointReference targetEPR = new EndpointReference(publisherEPR);
options.setTo(targetEPR);
options.setAction("urn:OpenPublicationSession");
options.setManageSession(true);
options.setUserName(user_name);
java.util.Map<String, Object> m = new java.util.HashMap<String, Object>();
/*m.put("javax.net.ssl.trustStorePassword", "wso2carbon");
m.put("javax.net.ssl.trustStore", "wso2carbon.jks");
*/
System.out.println(new Date() + " Checkpoint1");
// We are accessing STS over HTTPS - so need to set trustStore parameters.
System.setProperty("javax.net.ssl.trustStore", "client.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "apache");
/*m.put("javax.net.ssl.trustStore", "client.jks");
m.put("javax.net.ssl.trustStorePassword", "apache");*/
/*m.put("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin");
m.put("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
m.put("org.apache.ws.security.crypto.merlin.keystore.password","apache");
m.put("org.apache.ws.security.crypto.merlin.file", "client.jks");*/
//options.setProperties(m);
System.out.println(new Date() + " Checkpoint2");
client.setOptions(options);
MessageContext messageContext = new MessageContext();
messageContext.setOptions(options);
messageContext.setMessageID("MyMessageID");
System.out.println("provider:user_name: " + user_name);
messageContext.setProperty("username", user_name);
messageContext.setProperty("password", user_password);
MessageContext.setCurrentMessageContext(messageContext);
messageContext.setProperty("myproperty", "mypropertyvalue");
String falconNS = "http://cts.falcon.isbm";
falcon = fac.createOMNamespace(falconNS, "falcon");
OMElement falconUserElement = fac.createOMElement("FalconUser", falcon);
falconUserElement.setText(user_name);
client.addHeader(falconUserElement);
// invoke web-service
try {
errorText = "Client Didnt Respond.";
result = client.sendReceive(OpenPublicationSessionElement);
System.out.println(result.toString());
OMElement SessionIDElement = null;
SessionIDElement = result.getFirstChildWithName(new QName(namespace, "SessionID"));
SessionID = SessionIDElement.getText();
request.setAttribute("PublisherSession", SessionID);
StringBuffer text = new StringBuffer();
text.append((request.getParameter("TxtAreaServicePublisherLog")).trim());
text.trimToSize();
SessionID = SessionIDElement.getText();
StringBuffer publisherLog = new StringBuffer();
publisherLog.append((request.getParameter("TxtAreaServicePublisherLog")).trim());
publisherLog.trimToSize();
System.out.println("Checkpoint1");
publisherLog.append("\n" + new Date().toString() + " " + PUBLISHER_SESSION_SUCCESS_MSG + SessionID);
request.setAttribute("textMessageService2", publisherLog);
request.setAttribute("PublisherSession", SessionID);
System.out.println("Checkpoint3");
RequestDispatcher rd = request.getRequestDispatcher("/Provider.jsp");// hard-coded
try {
rd.forward(request, response);
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ServletException se) {
se.printStackTrace();
}
} catch (Exception e) {
errorText = "Client not responding";
buildErrorLog(request, response, e);
e.printStackTrace();
}
//buildCallLog(request, response, result);
} catch (Exception e) {
e.printStackTrace();
buildErrorLog(request, response, e);
}
}
And i have a proxy service upon which i have implemented security and its url is:
https://abc:8280/services/ProviderPublication.
My handle method inside callback handler is:
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
System.out.println("\n \n " + new Date() + " ISBMClient.PWCBHandler.handle");
if(MessageContext.getCurrentMessageContext() == null){
System.out.println("CurrentMessageContext is null");
}else{
//get the credentials from the jsp
System.out.println("MessageID: " + MessageContext.getCurrentMessageContext().getMessageID());
dynamicUser = MessageContext.getCurrentMessageContext().getProperty("username").toString();
dynamicPassword = MessageContext.getCurrentMessageContext().getProperty("password").toString();
System.out.println("MessageContext user_name: " + dynamicUser);
System.out.println("MessageContext user_password: " + dynamicPassword);
}
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
pwcb.setIdentifier(dynamicUser);
String id = pwcb.getIdentifier();
System.out.println("Invoking service with user: " + id);
if(dynamicUser.equals(id)){
pwcb.setPassword(dynamicPassword);
}
}
}
Now the problem is when i invoke this proxy service through my client code i am getting exception as
[INFO] Unable to sendViaPost to url[https://abc:8280/services/ProviderPublication]
org.apache.axis2.AxisFault: Trying to write END_DOCUMENT when document has no root (ie. trying to output empty document).
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:78)
at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:621)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:193)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:555)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:531)
at cts.falcon.isbm.client.Provider.publicationOpenSession(Provider.java:557)
at cts.falcon.isbm.client.Provider.doPost(Provider.java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.xml.stream.XMLStreamException: Trying to write END_DOCUMENT when document has no root (ie. trying to output empty document).
at com.ctc.wstx.sw.BaseStreamWriter.throwOutputError(BaseStreamWriter.java:1473)
at com.ctc.wstx.sw.BaseStreamWriter.reportNwfStructure(BaseStreamWriter.java:1502)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1663)
at com.ctc.wstx.sw.BaseStreamWriter.close(BaseStreamWriter.java:288)
at org.apache.axiom.util.stax.wrapper.XMLStreamWriterWrapper.close(XMLStreamWriterWrapper.java:46)
at org.apache.axiom.om.impl.MTOMXMLStreamWriter.close(MTOMXMLStreamWriter.java:222)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:192)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
... 38 more
But the same code is working for another web service written in eclipse. What am i doing wrong? Looking forward to your answers. Thanks in advance

You need to set SOAP envelope along with SOAP body which carries your payload from Service Client. I think that cause this problem. Please refer this blog post and refactor your code to add that.
http://amilachinthaka.blogspot.com/2009/09/sending-arbitrary-soap-message-with.html

A little late on the response here, but I ran into the same error message and after further digging it was due to some SSL certificate failures.
There were 2 ways to fix this:
Adding trusted certificate to Java using the keytool command.
OR
Using your own custom code to accept all certs (ex. below with a acceptallCerts() method)
public class SslUtil {
private static class SmacsTrustManager implements X509TrustManager {
#Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
#Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public static void acceptAllCerts(){
try{
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new SmacsTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);
}catch (Exception e){
}
}
}

Related

API Chorus Pro Oauth2 authentication in Java

I created an account on https://developer.aife.economie.gouv.fr/ website and I want to try API on the sandbox. For this an application has been generated
For this application, I obtain API key and OAuth2 Credentials. Here are my previous API keys.
By reading the documentation, I have the following entry points for authentication
My objective is to get authenticated and get an auth token in order to consume this API. Here is my code:
package com.oauth.app;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class OAuthApp {
/**
* URL for requesting OAuth access tokens.
*/
private static final String TOKEN_REQUEST_URL =
"https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";
/**
* Client ID of your client credential. Change this to match whatever credential you have created.
*/
private static final String CLIENT_ID =
"1f80aa43-e12f-4e1c-ad42-87ec16baf060";
/**
* Client secret of your client credential. Change this to match whatever credential you have created.
*/
private static final String CLIENT_SECRET =
"a232af0e-513e-4a64-9977-410d237dc421";
/**
* Account on which you want to request a resource. Change this to match the account you want to
* retrieve resources on.
*/
private static final String ACCOUNT_ID =
"a232af0e-513e-4a64-9977-410d237dc421";
/**
* Request a fresh access token using the given client ID, client secret, and token request URL,
* then request the resource at the given resource URL using that access token, and get the resource
* content. If an exception is thrown, print the stack trace instead.
*
* #param args Command line arguments are ignored.
*/
public static void main(String[] args) {
try {
OAuthClient client = new OAuthClient(new URLConnectionClient());
System.out.println("OAuthClient " + client.toString());
OAuthClientRequest request =
OAuthClientRequest.tokenLocation(TOKEN_REQUEST_URL)
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// .setScope() here if you want to set the token scope
.buildQueryMessage();
request.addHeader("Accept", "application/json");
// request.addHeader("Content-Type", "application/json");
// request.addHeader("Authorization", base64EncodedBasicAuthentication());
System.out.println("OAuthClientRequest body\n\t " + request.getBody());
System.out.println("OAuthClientRequest headers\n\t " + request.getHeaders());
System.out.println("OAuthClientRequest locationUri\n\t " + request.getLocationUri());
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
String token = client.accessToken(
request,
OAuth.HttpMethod.GET,
OAuthJSONAccessTokenResponse.class).getAccessToken();
} catch (OAuthSystemException | OAuthProblemException e) {
e.printStackTrace();
}
}
}
I obtain this in my console:
OAuthClient org.apache.oltu.oauth2.client.OAuthClient#7e0ea639
OAuthClientRequest body
null
OAuthClientRequest headers
{Accept=application/json, Content-Type=application/json}
OAuthClientRequest locationUri
https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token?grant_type=client_credentials&client_secret=a232af0e-513e-4a64-9977-410d237dc421&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27
OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
at org.apache.oltu.oauth2.common.exception.OAuthProblemException.error(OAuthProblemException.java:63)
at org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse.setBody(OAuthJSONAccessTokenResponse.java:76)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:92)
at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:65)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:101)
at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:60)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:120)
at org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory.createCustomResponse(OAuthClientResponseFactory.java:82)
at org.apache.oltu.oauth2.client.URLConnectionClient.execute(URLConnectionClient.java:111)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65)
at com.oauth.app.OAuthApp.main(OAuthApp.java:101)
I obtain this error message:
OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded'
I also tried to use a curl call to the API :
curl –k –H "content-type :application/x-www-form-urlencoded" –d "grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid" –X POST https://sandbox-oauth.aife.finances.rie.gouv.fr/api/oauth/token
curl: (6) Could not resolve host: -k
curl: (6) Could not resolve host: -H
curl: (3) Port number ended with 'a'
curl: (6) Could not resolve host: -d
curl: (6) Could not resolve host: grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid
curl: (6) Could not resolve host: -X
curl: (6) Could not resolve host: POST
curl: (6) Could not resolve host: sandbox-oauth.aife.finances.rie.gouv.fr
Ok i finally solved my own issue. There was no need to use OAuth stuff.
It's divided onto 2 classes. This code is just for testing purpose.
public class OAuthApp {
private static final String TOKEN_REQUEST_URL = "https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";
private static final String CLIENT_ID = "xxxxxx";
private static final String CLIENT_SECRET = "xxxxxx";
private static final String GRANT_TYPE = "client_credentials";
private static final String SCOPE = "openid";
public static void main(String[] args) throws IOException {
try {
Map<String, String> headers = new HashMap<>();
HttpsPostForm httpsPostForm = new HttpsPostForm(TOKEN_REQUEST_URL, "utf-8", headers);
httpsPostForm.addFormField("grant_type", GRANT_TYPE);
httpsPostForm.addFormField("client_id", CLIENT_ID);
httpsPostForm.addFormField("client_secret", CLIENT_SECRET);
httpsPostForm.addFormField("scope", SCOPE);
// Result
String response = httpsPostForm.finish();
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
My second class is just building the HTTPS request and set the headers elements. The empty trust manager helps to avoid error messages.
public class HttpsPostForm {
private HttpsURLConnection conn;
private Map<String, Object> queryParams;
private String charset;
public HttpsPostForm(String requestURL, String charset, Map<String, String> headers, Map<String, Object> queryParams) throws IOException {
this.charset = charset;
if (queryParams == null) {
this.queryParams = new HashMap<>();
} else {
this.queryParams = queryParams;
}
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
URL url = new URL(requestURL);
conn = (HttpsURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true); // indicates POST method
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
if (headers != null && headers.size() > 0) {
Iterator<String> it = headers.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String value = headers.get(key);
conn.setRequestProperty(key, value);
}
}
}
public HttpsPostForm(String requestURL, String charset, Map<String, String> headers) throws IOException {
this(requestURL, charset, headers, null);
}
public HttpsPostForm(String requestURL, String charset) throws IOException {
this(requestURL, charset, null, null);
}
public void addFormField(String name, Object value) {
queryParams.put(name, value);
}
public void addHeader(String key, String value) {
conn.setRequestProperty(key, value);
}
private byte[] getParamsByte(Map<String, Object> params) {
byte[] result = null;
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) {
postData.append('&');
}
postData.append(this.encodeParam(param.getKey()));
postData.append('=');
postData.append(this.encodeParam(String.valueOf(param.getValue())));
}
try {
result = postData.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
private String encodeParam(String data) {
String result = "";
result = URLEncoder.encode(data, StandardCharsets.UTF_8);
return result;
}
public String finish() throws IOException {
String response = "";
byte[] postDataBytes = this.getParamsByte(queryParams);
conn.getOutputStream().write(postDataBytes);
// Check the http status
int status = conn.getResponseCode();
if (status == HttpsURLConnection.HTTP_OK) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = conn.getInputStream().read(buffer)) != -1) {
result.write(buffer, 0, length);
}
response = result.toString(this.charset);
conn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
Finally I can print my Json string :
{
"access_token":"Js1NYJvtQREj0I0Dz5b0qrMh8gjJBlltJAit2Yx6BGJDloixPv2JwB",
"token_type":"Bearer",
"expires_in":3600,
"scope":"openid resource.READ"
}
I also had some difficulties with Chorus API but I achieve to get the tokenKey with that with the same method but buildBodyMessage() at the end.
// Création requête pour obtenir le token Oauth2 API CHORUS
request = OAuthClientRequest
.tokenLocation(urlToken)
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId(clientid)
.setClientSecret(clientsecret)
.setScope(OidcScopes.OPENID)
.buildBodyMessage();
// Ajout du Cpro-account
request.addHeader("cpro-account", cproAccount);
tokenChorus = client.accessToken(request, OAuth.HttpMethod.POST, OAuthJSONAccessTokenResponse.class)
.getAccessToken();
that create token formated in String. And afterthat you must create HttpUrlConnection with this token with headers like that
HttpURLConnection connexion = null;
try {
URL url = new URL(currentUrl);
connexion = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connexion.setRequestProperty("Content-type", "application/json");
connexion.setRequestProperty("Authorization", "Bearer " + tokenChorus);
connexion.setRequestProperty("cpro-account", cproAccount);
try {
connexion.setRequestMethod("POST");
} catch (ProtocolException e) {
e.printStackTrace();
}
connexion.setDoInput(true);
connexion.setDoOutput(true);
return connexion;

Need help on TLS 1.2 https service call from Java 1.4 client

I am facing issue while calling RestAPI call (which is running on Java 1.8 and TlS 1.2) using postmethod call from Java 1.4 client application. I have written below client code and I am end up with below issue.
I am providing the required .jks files in both trust store and keystore.
Error:
>java.security.KeyStoreException
>at com.ibm.jsse.bg.<init>(Unknown Source)
>at com.ibm.jsse.bo.a(Unknown Source)
>at com.ibm.jsse.bo.engineInit(Unknown Source)
>at javax.net.ssl.KeyManagerFactory.init(Unknown Source)
>bundles.ubuntu.vas.tiaa.AuthSSLProtocolSocketFactory.createKeyManagers(AuthSSLP>rotocolSocketFactory.java:223)
Code:
AuthSSLProtocolSocketFactory authSSLProtocolSocketFactory = new
AuthSSLProtocolSocketFactory(new URL("file:C:/cert/testwithsigner.jks"), "password1",
new URL("file:C:/cert/testwithsigner.jks"), "password1");
authSSLProtocolSocketFactory.createSocket("sample.intranet",8443);
final PostMethod post = new PostMethod("https://sample.intranet:8443/ext/ref/callservice");
HttpClient httpClient = new HttpClient();
post.setRequestHeader("Content-type", "application/json");
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
final int status = httpClient.executeMethod(post);
final InputStream is = post.getResponseBodyAsStream();
final StringBuffer content = new StringBuffer();
final String charset = post.getResponseCharSet();
Code:
public class AuthSSLProtocolSocketFactory implements SecureProtocolSocketFactory {
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(AuthSSLProtocolSocketFactory.class);
private URL keystoreUrl = null;
private String keystorePassword = null;
private URL truststoreUrl = null;
private String truststorePassword = null;
private SSLContext sslcontext = null;
public AuthSSLProtocolSocketFactory(
final URL keystoreUrl, final String keystorePassword,
final URL truststoreUrl, final String truststorePassword)
{
super();
this.keystoreUrl = keystoreUrl;
this.keystorePassword = keystorePassword;
this.truststoreUrl = truststoreUrl;
this.truststorePassword = truststorePassword;
}
private static KeyStore createKeyStore(final URL url, final String password)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
{
if (url == null) {
throw new IllegalArgumentException("Keystore url may not be null");
}
LOG.debug("Initializing key store");
KeyStore keystore = KeyStore.getInstance("jks");
InputStream is = null;
try {
is = url.openStream();
keystore.load(is, password != null ? password.toCharArray(): null);
} finally {
if (is != null) is.close();
}
return keystore;
}
private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password)
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
{
if (keystore == null) {
throw new IllegalArgumentException("Keystore may not be null");
}
LOG.debug("Initializing key manager");
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
if(password != null && password.toCharArray()!= null)
kmfactory.init(keystore, password.toCharArray());
return kmfactory.getKeyManagers();
}
private static TrustManager[] createTrustManagers(final KeyStore keystore)
throws KeyStoreException, NoSuchAlgorithmException
{
if (keystore == null) {
throw new IllegalArgumentException("Keystore may not be null");
}
LOG.debug("Initializing trust manager");
TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init(keystore);
TrustManager[] trustmanagers = tmfactory.getTrustManagers();
for (int i = 0; i < trustmanagers.length; i++) {
if (trustmanagers[i] instanceof X509TrustManager) {
trustmanagers[i] = new AuthSSLX509TrustManager(
(X509TrustManager)trustmanagers[i]);
}
}
return trustmanagers;
}
private SSLContext createSSLContext() {
try {
KeyManager[] keymanagers = null;
TrustManager[] trustmanagers = null;
if (this.keystoreUrl != null) {
KeyStore keystore = createKeyStore(this.keystoreUrl, this.keystorePassword);
//if (LOG.isDebugEnabled()) {
Enumeration aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String)aliases.nextElement();
Certificate[] certs = keystore.getCertificateChain(alias);
if (certs != null) {
LOG.debug("Certificate chain '" + alias + "':");
for (int c = 0; c < certs.length; c++) {
if (certs[c] instanceof X509Certificate) {
X509Certificate cert = (X509Certificate)certs[c];
System.out.println(" Certificate " + (c + 1) + ":");
System.out.println(" Subject DN: " + cert.getSubjectDN());
System.out.println(" Signature Algorithm: " + cert.getSigAlgName());
System.out.println(" Valid from: " + cert.getNotBefore() );
System.out.println(" Valid until: " + cert.getNotAfter());
System.out.println(" Issuer: " + cert.getIssuerDN());
}
}
}
}
// }
keymanagers = createKeyManagers(keystore, this.keystorePassword);
}
if (this.truststoreUrl != null) {
KeyStore keystore = createKeyStore(this.truststoreUrl, this.truststorePassword);
if (LOG.isDebugEnabled()) {
Enumeration aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String)aliases.nextElement();
LOG.debug("Trusted certificate '" + alias + "':");
Certificate trustedcert = keystore.getCertificate(alias);
if (trustedcert != null && trustedcert instanceof X509Certificate) {
X509Certificate cert = (X509Certificate)trustedcert;
LOG.debug(" Subject DN: " + cert.getSubjectDN());
LOG.debug(" Signature Algorithm: " + cert.getSigAlgName());
LOG.debug(" Valid from: " + cert.getNotBefore() );
LOG.debug(" Valid until: " + cert.getNotAfter());
LOG.debug(" Issuer: " + cert.getIssuerDN());
}
}
}
trustmanagers = createTrustManagers(keystore);
}
SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(keymanagers, trustmanagers, null);
return sslcontext;
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Unsupported algorithm exception: " + e.getMessage());
} catch (KeyStoreException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Keystore exception: " + e.getMessage());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Key management exception: " + e.getMessage());
} catch (IOException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("I/O error reading keystore/truststore file: " + e.getMessage());
}
}
private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext();
}
return this.sslcontext;
}
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException
{
return getSSLContext().getSocketFactory().createSocket(
host,
port
);
}
}

NPE when trying to use Jetty async HTTP client

When trying to use Firebase Cloud Messaging by Google with the help of non-blocking Jetty HTTP client in a simple test case that I have prepared at GitHub -
private static final HttpClient sHttpClient = new HttpClient();
private static final Response.ContentListener sFcmListener = new Response.ContentListener() {
#Override
public void onContent(Response response, ByteBuffer content) {
if (response.getStatus() != 200) {
return;
}
String body = StandardCharsets.UTF_8.decode(content).toString();
System.out.printf("onContent: %s\n", body);
Map<String, Object> resp = (Map<String, Object>) JSON.parse(body);
try {
Object[] results = (Object[]) resp.get(FCM_RESULTS);
Map result = (Map) results[0];
String error = (String) result.get(FCM_ERROR);
if (FCM_NOT_REGISTERED.equals(error)) {
// TODO delete invalid FCM token from the database
}
} catch (Exception ignore) {
}
}
};
public static void main(String[] args) throws Exception {
sHttpClient.start();
sHttpClient.POST(FCM_URL)
.header(HttpHeader.AUTHORIZATION, FCM_KEY)
.header(HttpHeader.CONTENT_TYPE, "application/json")
.content(new StringContentProvider(JSON.toString(REQUEST)))
.onResponseContent(sFcmListener)
.send();
}
but unfortunately the execution fails immediately with NPE:
2017-06-30 10:46:41.312:INFO::main: Logging initialized #168ms to org.eclipse.jetty.util.log.StdErrLog
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118)
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101)
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:682)
at de.afarber.fcmnotregistered.Main.main(Main.java:68)
Caused by: java.lang.NullPointerException
at org.eclipse.jetty.io.ssl.SslClientConnectionFactory.newConnection(SslClientConnectionFactory.java:59)
at org.eclipse.jetty.client.AbstractHttpClientTransport$ClientSelectorManager.newConnection(AbstractHttpClientTransport.java:191)
at org.eclipse.jetty.io.ManagedSelector.createEndPoint(ManagedSelector.java:420)
at org.eclipse.jetty.io.ManagedSelector.access$1600(ManagedSelector.java:61)
at org.eclipse.jetty.io.ManagedSelector$CreateEndPoint.run(ManagedSelector.java:599)
at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
at java.lang.Thread.run(Thread.java:745)
Why does it happen please?
UPDATE:
I have switched to using BufferingResponseListener and the NPE is gone, but now the program prints java.net.NoRouteToHostException: No route to host even though the Google FCM endpoint is a well-known host:
private static final HttpClient sHttpClient = new HttpClient();
private static final BufferingResponseListener sFcmListener = new BufferingResponseListener() {
#Override
public void onComplete(Result result) {
if (!result.isSucceeded()) {
System.err.println(result.getFailure()); // No route to host
return;
}
String body = getContentAsString(StandardCharsets.UTF_8);
System.out.printf("onContent: %s\n", body);
Map<String, Object> resp = (Map<String, Object>) JSON.parse(body);
try {
Object[] results = (Object[]) resp.get(FCM_RESULTS);
Map map = (Map) results[0];
String error = (String) map.get(FCM_ERROR);
if (FCM_NOT_REGISTERED.equals(error)) {
// TODO delete invalid FCM token from the database
}
} catch (Exception ex) {
System.err.println(ex);
}
}
};
public static void main(String[] args) throws Exception {
sHttpClient.start();
sHttpClient.POST(FCM_URL)
.header(HttpHeader.AUTHORIZATION, FCM_KEY)
.header(HttpHeader.CONTENT_TYPE, "application/json")
.content(new StringContentProvider(JSON.toString(REQUEST)))
.send(sFcmListener);
}
I get the No route to host for any FCM_URL value I try, why?
Adding SslContextFactory has helped me:
private static final SslContextFactory sFactory = new SslContextFactory();
private static final HttpClient sHttpClient = new HttpClient(sFactory);
private static final BufferingResponseListener sFcmListener = new BufferingResponseListener() {
#Override
public void onComplete(Result result) {
if (!result.isSucceeded()) {
System.err.println(result.getFailure());
return;
}
String body = getContentAsString(StandardCharsets.UTF_8);
System.out.printf("onComplete: %s\n", body);
try {
Map<String, Object> resp = (Map<String, Object>) JSON.parse(body);
Object[] results = (Object[]) resp.get(FCM_RESULTS);
Map map = (Map) results[0];
String error = (String) map.get(FCM_ERROR);
System.out.printf("error: %s\n", error);
if (FCM_NOT_REGISTERED.equals(error) ||
FCM_MISSING_REGISTRATION.equals(error) ||
FCM_INVALID_REGISTRATION.equals(error)) {
// TODO delete invalid FCM token from the database
}
} catch (Exception ex) {
System.err.println(ex);
}
}
};
public static void main(String[] args) throws Exception {
sHttpClient.start();
sHttpClient.POST(FCM_URL)
.header(HttpHeader.AUTHORIZATION, FCM_KEY)
.header(HttpHeader.CONTENT_TYPE, "application/json")
.content(new StringContentProvider(JSON.toString(REQUEST)))
.send(sFcmListener);
}
The still open question I have is how to retrieve the invalid FCM token that I have used in the Jetty HTTP client request, so that I can delete it from my database on the response...

Client and Server UDP transport layer

I need to send a message saying "Hi" from client to a server, the server will reply back to the client adding to the received message "Received", once the client receives this new message it will send this to another server and that server will add another message to the received message saying "Replied". So in the end the client will receive the message "Hi Received Replied".
Client code:
public class UDPClient{
public static void main(String args[]) {
// args[0] = message to be sent to the server;
// args[1] = IP address of the server
DatagramSocket aSocket=null;
try {
aSocket=new DatagramSocket();
byte [] m = args[0].getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m,args[0].length(), aHost, serverPort);
aSocket.send(request);
byte[] buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer,buffer.length);
aSocket.receive(reply);
System.out.println("Reply: " + new String(reply.getData(), 0, reply.getLength()));
}catch (SocketException e){System.out.println("Socket: " + e.getMessage());
}catch (IOException e){System.out.println("IO: " + e.getMessage());
}finally {
if(aSocket != null) aSocket.close();
}
}
}
Server Code:
public class UDPServer{
public static void main(String args[]) {
DatagramSocket aSocket = null;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer,buffer.length);
aSocket.receive(request);
System.out.println("Server is ready and waiting for requests ... ");
DatagramPacket reply = new DatagramPacket(request.getData(), request.getLength(),request.getAddress(), request.getPort());
}
}catch (SocketException e){System.out.println("Socket: " + e.getMessage());
}catch (IOException e) {System.out.println("IO: " + e.getMessage());
}finally {
if(aSocket != null) aSocket.close();
}
}
}

Error when processing the authentication request in WSO2 Identity Server - NullPointerException

I'm having a trouble when authenticating with the WSO2 Identity Server.
I have a web page named avis.com, when I enter the page, click the login button, then the web page navigates to the login form of WSO2 Identity Server. But, when I enter use name and password into the form and click login. A error page appears as:
SAML 2.0 based Single Sign-On
Error when processing the authentication request!
Please try login again.
At the Apache Tomcat Log, errors appear:
Nov 07, 2013 3:12:32 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [SAML2ConsumerServlet] in context with path [/travelocity.com] threw exception
java.lang.NullPointerException
at com.travelocity.saml.sso.SamlConsumerManager.getResult(SamlConsumerManager.java:272)
at com.travelocity.saml.sso.SamlConsumerManager.processResponseMessage(SamlConsumerManager.java:246)
at com.travelocity.saml.sso.SAML2ConsumerServlet.doPost(SAML2ConsumerServlet.java:73)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
At the com.avis.saml.sso.SamlConsumerManager.getResult(SamlConsumerManager.java:272):
private Map<String, String> getResult(XMLObject responseXmlObj) {
if (responseXmlObj.getDOM().getNodeName().equals("saml2p:LogoutResponse")) //line 722{
return null;
}
Response response = (Response) responseXmlObj;
Assertion assertion = response.getAssertions().get(0);
Map<String, String> resutls = new HashMap<String, String>(); // line 72
/*
* If the request has failed, the IDP shouldn't send an assertion.
* SSO profile spec 4.1.4.2 <Response> Usage
*/
if (assertion != null) {
String subject = assertion.getSubject().getNameID().getValue();
resutls.put("Subject", subject); // get the subject
List<AttributeStatement> attributeStatementList = assertion.getAttributeStatements();
if (attributeStatementList != null) {
// we have received attributes of user
Iterator<AttributeStatement> attribStatIter = attributeStatementList.iterator();
while (attribStatIter.hasNext()) {
AttributeStatement statment = attribStatIter.next();
List<Attribute> attributesList = statment.getAttributes();
Iterator<Attribute> attributesIter = attributesList.iterator();
while (attributesIter.hasNext()) {
Attribute attrib = attributesIter.next();
Element value = attrib.getAttributeValues().get(0).getDOM();
String attribValue = value.getTextContent();
resutls.put(attrib.getName(), attribValue);
}
}
}
}
return resutls;
}
At the com.avis.saml.sso.SAML2ConsumerServlet.doPost(SAML2ConsumerServlet.java:72)
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
String responseMessage = request.getParameter("SAMLResponse");
if (responseMessage != null) { /* response from the identity provider */
Map<String, String> result = consumer.processResponseMessage(responseMessage);
if (result != null && result.size() == 1) {
/*
* No user attributes are returned, so just goto the default
* home page.
*/
response.sendRedirect("home.jsp?subject=" + result.get("Subject"));
} else if (request != null && result.size() > 1) {
/*
* We have received attributes, so lets show them in the
* attribute home page.
*/
String params = "home-attrib.jsp?";
Object[] keys = result.keySet().toArray();
for (int i = 0; i < result.size(); i++) {
String key = (String) keys[i];
String value = (String) result.get(key);
if (i != result.size()) {
params = params + key + "=" + value + "&";
} else {
params = params + key + "=" + value;
}
}
response.sendRedirect(params);
} else {
// something wrong, re-login
response.sendRedirect("index.jsp");
}
} else { /* time to create the authentication request or logout request */
try {
String requestMessage = consumer.buildRequestMessage(request);
response.sendRedirect(requestMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
At the com.avis.saml.sso.SamlConsumerManager.processResponseMessage(SamlConsumerManager.java:246)
public Map<String, String> processResponseMessage(String responseMessage) {
XMLObject responseXmlObj = null;
try {
responseXmlObj = unmarshall(responseMessage);
} catch (ConfigurationException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnmarshallingException e) {
e.printStackTrace();
}
return getResult(responseXmlObj); // line 246
}
Actually, I have two web pages, but here I mentioned one because they are the same. I'm doing a single sign on project that two service provider (web pages) are central authenticated at WSO2 Identity Server using SAML2.0 and OpenSAML
I don't know whether I miss some step when configure or not? Are there any important point I must keep in mind for my web page to authenticate successfully.
I was getting the same exception.Updating unmarshall method as below resolved my problem.
private XMLObject unmarshall(String responseMessage) throws ConfigurationException,
ParserConfigurationException, SAXException,
IOException, UnmarshallingException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
byte[] base64DecodedResponse = responseMessage.getBytes("UTF-8");
byte[] decoded = Base64.decode(base64DecodedResponse,0,responseMessage.length());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
String s = new String(decoded,StandardCharsets.UTF_8);
Document document = docBuilder.parse(new InputSource(new StringReader(s)));
Element element = document.getDocumentElement();
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
return unmarshaller.unmarshall(element);
}