oracle.stellent.ridc.protocol.http.HttpProtocolException: Http status: HTTP/1.1 401 Authorization Required - oracle-ucm

I am facing some issues while pinging the server With RIDC code for oracle UCM 10 g and i am getting HTTP/1.1 401 Authorization Required exception.
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.stellent.ridc.IdcClient;
import oracle.stellent.ridc.IdcClientException;
import oracle.stellent.ridc.IdcClientManager;
import oracle.stellent.ridc.IdcContext;
import oracle.stellent.ridc.model.DataBinder;
import oracle.stellent.ridc.protocol.ServiceResponse;
public class PingGuest {
IdcClientManager manager = new IdcClientManager();
IdcClient idcClient;
public PingGuest() throws IdcClientException {
this.idcClient = manager.createClient("Server Address");
idcClient.getConfig ().setProperty ("http.library", "apache4");
IdcContext userPasswordContext = new IdcContext("user", "pass");
DataBinder dataBinder = this.idcClient.createBinder ();
dataBinder.putLocal ("IdcService", "PING_SERVER");
ServiceResponse response = idcClient.sendRequest (userPasswordContext, dataBinder);
}
public static void main(String args[]){
try {
new PingGuest();
} catch (IdcClientException ex) {
Logger.getLogger(PingGuest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This is the error.
oracle.stellent.ridc.protocol.http.HttpProtocolException: Http status: HTTP/1.1 401 Authorization Required
Any kind of help is appreciated.

You have omitted your server address. I understand why you omitted it, but getting that wrong might cause the issue you are seeing. If you've read newer documentation, keep in mind that it differs a bit in the older versions.

Related

OAuth2RestTemplate for Salesforce is giving error - HTTP 400 Bad Request

I am trying to integrate Spring Boot with Salesforce using OAuth2RestTemplate but it is giving me Access token denied error even though credentials are correct. Upon debugging I found that Salesforce is sending 400 HTTP status code.
package com.sentryds.advis.salesforce;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
#SpringBootApplication
public class SalesforceApplication {
public static void main(String[] args) {
SpringApplication.run(SalesforceApplication.class, args);
ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
resourceDetails.setAuthenticationScheme(AuthenticationScheme.form);
resourceDetails.setAccessTokenUri("https://test.salesforce.com/services/oauth2/token");
resourceDetails.setGrantType("password");
resourceDetails.setClientId("xxxxxxxx");
resourceDetails.setClientSecret("xxxxxxxx");
resourceDetails.setUsername("xxxxxxxx");
resourceDetails.setPassword("xxxxxxxx");
OAuth2RestTemplate auth2RestTemplate = new OAuth2RestTemplate(resourceDetails);
try {
System.out.println(auth2RestTemplate.getAccessToken());
} catch (Throwable t) {
System.out.println(t.getMessage());
}
}
}
However if I following this technique then everything works. Only reason I am using OAuth2RestTemplate is because it takes care of the token refresh automatically. If there is another way to do so without using OAuthRestTemplate then please let me know that as well.
Finally I was able to solve this problem. I am posting my answer with a hope that it will help someone.
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setAccessTokenUri("https://test.salesforce.com/services/oauth2/token");
resource.setClientId("client_id");
resource.setClientSecret("client_secret");
resource.setClientAuthenticationScheme(AuthenticationScheme.form);
resource.setUsername("username");
resource.setPassword("password");
OAuth2RestTemplate operations = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
operations.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); // Not required if you are not doing any conversion
operations.getMessageConverters().add(new StringHttpMessageConverter()); // Not required if you are not doing any conversion
try {
System.out.println(auth2RestTemplate.getAccessToken());
} catch (Throwable t) {
System.out.println(t.getMessage());
}

OpenShift: Cannot Connect to WebSocket with Alias (bug)

I have a Java Spring Web application which uses WebSockets. An HTML file connects to the WebSocket using the uri:
var wsUri = "wss://" + document.location.hostname + ":8443" + "/serverendpoint";
Here is my serverendpoint.java code that creates the WebSocket:
package com.myapp.spring.web.controller;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.web.socket.server.standard.SpringConfigurator;
#ServerEndpoint(value="/serverendpoint", configurator = SpringConfigurator.class)
public class serverendpoint {
#OnOpen
public void handleOpen () {
System.out.println("JAVA: Client is now connected...");
}
#OnMessage
public String handleMessage (Session session, String message) throws IOException {
if (message.equals("ping")) {
// return "pong"
session.getBasicRemote().sendText("pong");
}
else if (message.equals("close")) {
handleClose();
return null;
}
System.out.println("JAVA: Received from client: "+ message);
MyClass mc = new MyClass(message);
String res = mc.action();
session.getBasicRemote().sendText(res);
return res;
}
#OnClose
public void handleClose() {
System.out.println("JAVA: Client is now disconnected...");
}
#OnError
public void handleError (Throwable t) {
t.printStackTrace();
}
}
When I connect to the websocket using the http://myapp-myproject.rhcloud.com/mt URL, the WebSocket connects. However, when I set up an alias to the http://myapp-myproject.rhcloud.com, which is called https://someurl.com/mt, the websocket doesn't connect. Why is this? I get the following error message in Google Chrome:
Furthermore, the websocket uses a wss connection at port 8443. This is a secure request equivalent to https. Therefore, how can it work with the http://myapp-myproject.rhcloud.com/mt URL which is an http URL, and why is it not connecting with the alias?
Thank you so much for your help!

How to register my custom MessageBodyReader in my CLIENT?

Maybe somebody can help me find out how to solve this.
I am using jersey-apache-client 1.17
I tried to use Jersey client to build a standalone application (no Servlet container or whatever, just the Java classes) which communicates with a RESTFUL API, and everything worked fine until I tried to handle the mediatype "text/csv; charset=utf-8" which is a CSV stream sent by the server.
The thing is that I can read this stream with the following code:
InputStreamReader reader = new InputStreamReader(itemExportBuilder
.get(ClientResponse.class).getEntityInputStream());
Csv csv = new Csv();
Input input = csv.createInput(reader);
try {
String[] readLine;
while ((readLine = input.readLine()) != null) {
LOG.debug("Reading CSV: {}", readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
But I'd like to encapsulate it and put it into a MessageBodyReader. But after writing this code, I just can't make the client use the following class:
package client.response;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Provider
public class ItemExportMessageBodyReader implements MessageBodyReader<ItemExportResponse> {
private static final Logger LOG = LoggerFactory.getLogger(ItemExportMessageBodyReader.class);
private static final Integer SKU = 0;
private static final Integer BASE_SKU = 1;
public boolean isReadable(Class<?> paramClass, Type type, Annotation[] annotations,
MediaType mediaType) {
LOG.info("Cheking if content is readable or not");
return paramClass == ItemExportResponse.class && !mediaType.isWildcardType()
&& !mediaType.isWildcardSubtype()
&& mediaType.isCompatible(MediaType.valueOf("text/csv; charset=utf-8"));
}
public ItemExportResponse readFrom(Class<ItemExportResponse> paramClass, Type paramType,
Annotation[] paramArrayOfAnnotation, MediaType paramMediaType,
MultivaluedMap<String, String> paramMultivaluedMap, InputStream entityStream)
throws IOException, WebApplicationException {
InputStreamReader reader = new InputStreamReader(entityStream);
Csv csv = new Csv();
Input input = csv.createInput(reader);
List<Item> items = new ArrayList<Item>();
try {
String[] readLine;
while ((readLine = input.readLine()) != null) {
LOG.trace("Reading CSV: {}", readLine);
Item item = new Item();
item.setBaseSku(readLine[BASE_SKU]);
items.add(item);
}
} catch (IOException e) {
LOG.warn("Item export HTTP response handling failed", e);
} finally {
try {
input.close();
} catch (IOException e) {
LOG.warn("Could not close the HTTP response stream", e);
}
}
ItemExportResponse response = new ItemExportResponse();
response.setItems(items);
return response;
}
}
The following documentation says that the preferred way of making this work in a JAX-RS client to register the message body reader with the code below:
Using Entity Providers with JAX-RS Client API
Client client = ClientBuilder.newBuilder().register(MyBeanMessageBodyReader.class).build();
Response response = client.target("http://example/comm/resource").request(MediaType.APPLICATION_XML).get();
System.out.println(response.getStatus());
MyBean myBean = response.readEntity(MyBean.class);
System.out.println(myBean);
Now the thing is that I can't use the ClientBuilder. I have to extend from a specific class which constructs the client another way, and I have no access to change the construction.
So when I receive the response from the server, the client fails with the following Exception:
com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class client.response.ItemExportResponse, and Java type class client.response.ItemExportResponse, and MIME media type text/csv; charset=utf-8 was not found
Any other way to register my MessageBodyReader?
OK. If anybody would bump into my question I solved this mystery by upgrading from Jersey 1.17 to version 2.9. The documentation I linked above also covers this version not the old one, this is where the confusion stems from.
Jersey introduced backward INCOMPATIBLE changes starting from version 2, so I have no clue how to configure it in version 1.17.
In version 2 the proposed solution worked fine.

CXF InInterceptor not firing

I have created web service. It works fine. Now I'm trying to implement authentication to it. I'm using CXF interceptors for that purpose. For some reason interceptors won't fire. What am I missing? This is my first web service.
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import org.apache.cxf.interceptor.InInterceptors;
#WebService
#InInterceptors(interceptors = "ws.BasicAuthAuthorizationInterceptor")
public class Service {
#WebMethod
public void test(#WebParam(name = "value") Integer value) throws Exception {
System.out.println("Value = " + value);
}
}
-
package ws;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.Conduit;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
public class BasicAuthAuthorizationInterceptor extends SoapHeaderInterceptor {
#Override
public void handleMessage(Message message) throws Fault {
System.out.println("**** GET THIS LINE TO CONSOLE TO SEE IF INTERCEPTOR IS FIRING!!!");
AuthorizationPolicy policy = message.get(AuthorizationPolicy.class);
// If the policy is not set, the user did not specify credentials.
// 401 is sent to the client to indicate that authentication is required.
if (policy == null) {
sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED);
return;
}
String username = policy.getUserName();
String password = policy.getPassword();
// CHECK USERNAME AND PASSWORD
if (!checkLogin(username, password)) {
System.out.println("handleMessage: Invalid username or password for user: "
+ policy.getUserName());
sendErrorResponse(message, HttpURLConnection.HTTP_FORBIDDEN);
}
}
private boolean checkLogin(String username, String password) {
if (username.equals("admin") && password.equals("admin")) {
return true;
}
return false;
}
private void sendErrorResponse(Message message, int responseCode) {
Message outMessage = getOutMessage(message);
outMessage.put(Message.RESPONSE_CODE, responseCode);
// Set the response headers
#SuppressWarnings("unchecked")
Map<String, List<String>> responseHeaders = (Map<String, List<String>>) message
.get(Message.PROTOCOL_HEADERS);
if (responseHeaders != null) {
responseHeaders.put("WWW-Authenticate", Arrays.asList(new String[] { "Basic realm=realm" }));
responseHeaders.put("Content-Length", Arrays.asList(new String[] { "0" }));
}
message.getInterceptorChain().abort();
try {
getConduit(message).prepare(outMessage);
close(outMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
private Message getOutMessage(Message inMessage) {
Exchange exchange = inMessage.getExchange();
Message outMessage = exchange.getOutMessage();
if (outMessage == null) {
Endpoint endpoint = exchange.get(Endpoint.class);
outMessage = endpoint.getBinding().createMessage();
exchange.setOutMessage(outMessage);
}
outMessage.putAll(inMessage);
return outMessage;
}
private Conduit getConduit(Message inMessage) throws IOException {
Exchange exchange = inMessage.getExchange();
EndpointReferenceType target = exchange.get(EndpointReferenceType.class);
Conduit conduit = exchange.getDestination().getBackChannel(inMessage, null, target);
exchange.setConduit(conduit);
return conduit;
}
private void close(Message outMessage) throws IOException {
OutputStream os = outMessage.getContent(OutputStream.class);
os.flush();
os.close();
}
}
I'm fighting with this for few days now. Don't know what to google any more. Help is appreciated.
I've found solution. I was missing the following line in MANIFEST.MF file in war project:
Dependencies: org.apache.cxf
Maven wasn't includint this line by himself so I had to find workaround. I found about that here. It says: When using annotations on your endpoints / handlers such as the Apache CXF ones (#InInterceptor, #GZIP, ...) remember to add the proper module dependency in your manifest. Otherwise your annotations are not picked up and added to the annotation index by JBoss Application Server 7, resulting in them being completely and silently ignored.
This is where I found out how to change MANIFEST.MF file.
In short, I added custom manifest file to my project and referenced it in pom.xml. Hope this helps someone.
The answer provided by Felix is accurate. I managed to solve the problem using his instructions. Just for completion here is the maven config that lets you use your own MANIFEST.MF file placed in the META-INF folder.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
and here is the relevant content of the content of the MANIFEST.MF file I was using.
Manifest-Version: 1.0
Description: yourdescription
Dependencies: org.apache.ws.security,org.apache.cxf

How to convert a string to an Apache HttpComponents HttpRequest

I have a String that contains an HTTP header. I want to turn this into an Apache HttpComponents HttpRequest object. Is there a way to do this without picking apart the string myself?
This tutorial: http://hc.apache.org/httpcomponents-core-dev/tutorial/html/fundamentals.html#d5e56 and the javadoc does not indicate as much.
A class to convert a string to apache request:
import org.apache.http.*;
import org.apache.http.impl.DefaultHttpRequestFactory;
import org.apache.http.impl.entity.EntityDeserializer;
import org.apache.http.impl.entity.LaxContentLengthStrategy;
import org.apache.http.impl.io.AbstractSessionInputBuffer;
import org.apache.http.impl.io.HttpRequestParser;
import org.apache.http.io.HttpMessageParser;
import org.apache.http.io.SessionInputBuffer;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicLineParser;
import org.apache.http.params.BasicHttpParams;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
*
*/
public class ApacheRequestFactory {
public static HttpRequest create(final String requestAsString) {
try {
SessionInputBuffer inputBuffer = new AbstractSessionInputBuffer() {
{
init(new ByteArrayInputStream(requestAsString.getBytes()), 10, new BasicHttpParams());
}
#Override
public boolean isDataAvailable(int timeout) throws IOException {
throw new RuntimeException("have to override but probably not even called");
}
};
HttpMessageParser parser = new HttpRequestParser(inputBuffer, new BasicLineParser(new ProtocolVersion("HTTP", 1, 1)), new DefaultHttpRequestFactory(), new BasicHttpParams());
HttpMessage message = parser.parse();
if (message instanceof BasicHttpEntityEnclosingRequest) {
BasicHttpEntityEnclosingRequest request = (BasicHttpEntityEnclosingRequest) message;
EntityDeserializer entityDeserializer = new EntityDeserializer(new LaxContentLengthStrategy());
HttpEntity entity = entityDeserializer.deserialize(inputBuffer, message);
request.setEntity(entity);
}
return (HttpRequest) message;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (HttpException e) {
throw new RuntimeException(e);
}
}
}
and a test class showing how to use it:
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import static org.junit.Assert.*;
/**
*
*/
public class ApacheRequestFactoryTest {
#Test
public void testGet() {
String requestString = "GET /?one=aone&two=atwo HTTP/1.1\n" +
"Host: localhost:7788\n" +
"Connection: Keep-Alive\n" +
"User-Agent: Apache-HttpClient/4.0.1 (java 1.5)";
HttpRequest request = ApacheRequestFactory.create(requestString);
assertEquals("GET", request.getRequestLine().getMethod());
List<NameValuePair> pairs = URLEncodedUtils.parse(URI.create(request.getRequestLine().getUri()), "ISO-8859-1");
checkPairs(pairs);
}
#Test
public void testPost() throws IOException {
String requestString = "POST / HTTP/1.1\n" +
"Content-Length: 17\n" +
"Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1\n" +
"Host: localhost:7788\n" +
"Connection: Keep-Alive\n" +
"User-Agent: Apache-HttpClient/4.0.1 (java 1.5)\n" +
"\n" +
"one=aone&two=atwo";
HttpRequest request = ApacheRequestFactory.create(requestString);
assertEquals("POST", request.getRequestLine().getMethod());
List<NameValuePair> pairs = URLEncodedUtils.parse(((BasicHttpEntityEnclosingRequest)request).getEntity());
checkPairs(pairs);
}
private void checkPairs(List<NameValuePair> pairs) {
for (NameValuePair pair : pairs) {
if (pair.getName().equals("one")) assertEquals("aone", pair.getValue());
else if (pair.getName().equals("two")) assertEquals("atwo", pair.getValue());
else assertTrue("got more parameters than expected:"+pair.getName(), false);
}
}
}
And a small rant:
WHAT ARE THE APACHE HTTP TEAM THINKING ? The api is incredibly awkward to use. Developers around the world are wasting time writing wrapper and conversion classes for what should be run of the mill every day usage (like this example the simple act of converting a string to an apache http request, and the bizarre way you need to extract the form parameters (also having to do it in two different ways depending on what type of request was made)). The global time wasted because of this is huge. When you write an API from the bottom up, starting with the specs, you MUST then start a layer from the top down (top being an interface where you can get typical work done without having to understand or look at the way the code is implemented), making every day usage of the library CONVENIENT and intuitive. Apache http libraries are anything but. It's almost a miracle that its the standard library for this type of task.

Resources