Jax-WS with NTLM authentification - java

As I read Jax-ws can authenticate with NTLM, but I have a problem;
First of all I create MyAuthenticator java class as describe in java documentation(see:
http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-auth.html).
when I try to connect with soapUI everything is Ok, see request header:
Request Headers Value
(Request-Line) POST /Online/OnlineServices.asmx HTTP/1.1
Content-Type text/xml;charset=UTF-8
SOAPAction "http://CTL.COM/OnlineServices/AcquireTicket"
Host 172.22.2.144:8000
Connection Keep-Alive
User-Agent Apache-HttpClient/4.1.1 (java 1.5)
Authorization NTLM TlRMTVNTUAADAAAAGAAYAEAAAACgAKAAWAAAAAYABgD4AAAAGAAYAP4AAAAMAAwAFgEAAAAAAAAiAQAA
Accept-Encoding gzip, deflate
Content-Length 702
when I try to connect with java, I got 500 Internal server error, see header:
Request Headers Value
(Request-Line) POST /Online/OnlineServices.asmx HTTP/1.1
SOAPAction "http://CTL.COM/OnlineServices/AcquireTicket"
Accept text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type text/xml;charset="utf-8"
User-Agent JAX-WS RI 2.1.4-b01-
Host 172.22.2.144:8000
Connection keep-alive
Authorization NTLM TlRMTVNTUAADAAAAGAAYAIwAAAD8APwApAAAAAYABgBYAAAAIgAiAF4AAAAMAAwAgAAAAAAAAACgAQAABYKIogoAOTgAAAAP5/lqdc43ElnLlEh5ASEkQlUARgBDAGUAdgBnAGUAbgBpAC4AbwByAG0AbwB0AHMAYQBkAHoAZQBQAEMALQAyADMAMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXZ
Accept-Encoding gzip, deflate
Content-Length 443
this is my code :
Authenticator.setDefault(new MyAuthenticator(domain + "\\kuser","kpass"));
OnlineServicesSoap onlineServicesSoap = new OnlineServices(url,qName).getOnlineServicesSoap();
Map<String, List<String>> headers = new HashMap<String, List<String>>(); headers.put("Content-Type", Collections.singletonList("text/xml;charset=UTF-8"));
headers.put("Accept-Encoding", Collections.singletonList("gzip, deflate"));
((BindingProvider)onlineServicesSoap).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, headers);
try {
AcquireTicketResponse acquireTicketResponse =
onlineServicesSoap.acquireTicket(acqTicket);
} catch (RuntimeException ex) {
System.out.println(ex.getMessage() + ex.getCause());
}
I searched a lot and found some posts suggesting to do NTLM authentication but I couldn't to connect.. I don't want to use axis implementation

Related

403 Forbidden error from SprintBoot RestTemplate but working fine from Postman

With a given token, Postman can hit the Microsoft Graph API successfully, whereas the SpringBoot RestTemplate gives the 403 Forbidden error.
From Postman:
GET https://graph.microsoft.com/beta/me/profile/
Authorization: Bearer <token>
User-Agent: PostmanRuntime/7.26.8
Cache-Control: no-cache
Host: graph.microsoft.com
Accept-Encoding: gzip, deflate
Connection: keep-alive
Accept: */*
From SpringBoot Apache Logs:
GET /beta/me/profile/ HTTP/1.1
Authorization: Bearer <token>
Cache-Control: no-cache
User-Agent: PostmanRuntime/7.26.8 (I hardcoded it to make everything same as postman)
Host: graph.microsoft.com
Connection: Keep-Alive
Accept-Encoding: gzip,deflate
Accept: */*
Here is the sample code that I was using:
#GetMapping("/test")
public String test() {
String token = "removed for now";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setBearerAuth(token);
httpHeaders.setAccept(Arrays.asList(MediaType.ALL));
httpHeaders.setCacheControl("no-cache");
httpHeaders.add(HttpHeaders.USER_AGENT, "PostmanRuntime/7.26.8");
HttpEntity httpEntity = new HttpEntity(httpHeaders);
ResponseEntity<String> exchange = restTemplate.exchange("https://graph.microsoft.com/beta/me/profile/",
HttpMethod.GET,
httpEntity,
String.class);
return exchange.getBody();
}
I tried several suggestions but couldn't figure it out. Any idea on what might be going wrong?

How to disable cxf SOAP client use multipart request

I have to call a proprietary service that does not support multipart requests, I'm not sending any attachments but cxf seems to create a multipart request
POST /endpoint HTTP/1.1
Content-Type: multipart/related; type="text/xml"; boundary="uuid:86ebef4f-fc2a-431b-a21b-37e86b4901f9"; start="<root.message#cxf.apache.org>"; start-info="text/xml"
Accept: */*
Authorization: Basic U1dHMTAwNTA6MTIzNDU1
SOAPAction: "XYZ.0050"
User-Agent: Apache-CXF/3.3.6
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:8082
Connection: keep-alive
Content-Length: 2134
--uuid:86ebef4f-fc2a-431b-a21b-37e86b4901f9
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <root.message#cxf.apache.org>
[etc...]
I've noticed a non-multipart request works fine
POST /endpoint HTTP/1.1
Content-Type: text/xml;charset=UTF-8
Accept: */*
Authorization: Basic U1dHMTAwNTA6MTIzNDU1
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8082
Pragma: no-cache
SOAPAction: "XYZ.0050"
User-Agent: Apache-CXF/3.3.6
Content-Length: 2114
[etc...]
How do I force cxf to use a non-multipart request?
it looks like cxf creates a multipart any time there is a #XmlAttachmentRef / DataHandler attribute, in my case it is never used so I removed it from my classes.
a better solution would be to remove the SwAOutInterceptor from the interceptor chain by definining an interceptor remover
class InterceptorRemover : AbstractSoapInterceptor(Phase.PRE_LOGICAL) {
init {
addBefore(SwAOutInterceptor::class.java.name)
}
override fun handleMessage(message: SoapMessage?) {
if (message != null) {
val res = message.interceptorChain.firstOrNull() { it is SwAOutInterceptor }
if (res != null) {
message.interceptorChain.remove(res)
}
}
}
}
and add it to the chain:
val client = ClientProxy.getClient(port)
client.outInterceptors.add(InterceptorRemover())

OAuth2 oltu client

I'm building my oauth2-protecet webservice, and a client. For webservice I used spring security implementation, and used this as example. For client I'm trying out apache oltu library. Here's my snippet:
OAuthClientRequest request = OAuthClientRequest.tokenLocation
("http://localhost:8080/oauth/token")
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId("clientapp")
.setClientSecret("123456")
.buildHeaderMessage();
OAuthAccessTokenResponse oAuthResponse = cli.accessToken(request);
System.out.println(oAuthResponse.getAccessToken());
It does not work. While this
curl -X POST -vu clientapp:123456 --data "grant_type=client_credentials&client_secret=123456&client_id=clientapp" http://localhost:8080/oauth/token
works perfectly well. Here's the curl request:
POST /oauth/token HTTP/1.1
Authorization: Basic Y2xpZW50YXBwOjEyMzQ1Ng==
User-Agent: curl/7.35.0
Host: localhost:8080
Accept: */*
Content-Length: 70
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_secret=123456&client_id=clientapp
as you can see, I used Basic authentication with curl and it worked(even though suggested authentication type is Bearer).
And here's oltu packet:
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer client_credentials123456clientapp
User-Agent: Java/1.8.0_51
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 4
null
I'm nor sure how bearer authorization is supposed to work, but this packet looks all wrong.
I also tried to use buildBodyMessage() and buildQueryMessage() instead of buildHeaderessage() as was suggested in this post, but it's no good either.
This line doesnt look very healthy:
Authorization: Bearer client_credentials123456clientapp
I created a test server with Oltu, basically a servlet:
OAuthResponse oauthResponse = OAuthASResponse
.tokenResponse(HttpServletResponse.SC_OK)
.setAccessToken(accessToken)
.setExpiresIn(Integer.toString(expires))
.setRefreshToken(refreshToken)
.buildJSONMessage();
response.setStatus(oauthResponse.getResponseStatus());
response.setContentType("application/json");
And for the client I got:
OAuthClientRequest request = OAuthClientRequest
.tokenLocation("http://localhost:8083/OltuServer/token")
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId("clientapp")
.setClientSecret("123456")
.buildQueryMessage();
OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(request);
System.out.println(oAuthResponse.getAccessToken());
The main difference from your code is buildQueryMessage(). Using buildHeaderMessage() I get an exception on the server
OAuthProblemException {error='invalid_request', description='Missing grant_type parameter value' ... }
But I see that Oltu is at version 1.0.1 now while I've been testing on 1.0.0. That version might behave different.
The following appeared to work for me:
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthClientRequest bearerClientRequest = OAuthClientRequest.tokenLocation("http://localhost/rest/auth")
.setUsername("userid")
.setPassword("Password01")
.buildQueryMessage();
bearerClientRequest.setHeader(OAuth.HeaderType.CONTENT_TYPE, "multipart/form-data");
OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.POST, OAuthResourceResponse.class);

Resteasy always get application/json content type on request

I have a web application that use Angularjs on frontend och Resteasy + Jackson on the back end. I'm sending a file from Angular component to a REST method, receiving method looks like this :
#POST
#Path("/upload/attachment/for/{eventId}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultipartFormDataInput input,
final #PathParam("eventId") Long eventId,
#Context HttpServletRequest request) {
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
...my awesome stuff...
return Response.ok().build();
}
And request has following headers when sent :
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length 347085
Content-Type multipart/form-data; boundary=---------------------------12164806981346771846716776342
Cookie JSESSIONID=aoBd1hgzR3GM8bSG5P-9g-vQ; csrftoken=ziQ7kN7TlMehR2aURDrmaMLYAroMsSpu
Host localhost:9000
Referer http://localhost:9000/local/myapp/index.html
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:32.0) Gecko/20100101 Firefox/32.0
The problem is that THIS request ALWAYS has application/json as a Content-Type instead for multipart/form-data as it says in the headers. And I get :
20:12:00,490 WARN [org.jboss.resteasy.core.SynchronousDispatcher] (http-/127.0.0.1:8080-2) Failed executing POST /events/upload/attachment/for/null: org.jboss.resteasy.spi.UnsupportedMediaTypeException: Cannot consume content type
Already in HttpServletDispatcher the content is wrong.
I can't get if this is JBOSS that set Content-Type to wrong value or some thing else.
Ok, it was that I have an extra layer between angular and server which runs on Node.js and it just tunel requests to the server. I had to add following :
var r = null;
r = request.put({uri: url, json: inReq.body, headers: inReq.headers, form: inReq.form});
inReq.pipe(r).pipe(inRes);
This set all the headers from outgoing request and tunnel the request
Now I have right content-type

Spring ws Operation 'message' is not defined in the WSDL for this service

Hi I'm trying to create a soap client using spring-ws. I tried whith the following code:
public void test1() {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setDefaultUri("the url of my web service");
StreamSource source = new StreamSource(new StringReader("<message xmlns=\"http://tempuri.org\">Hello Web Service World</message>"));
StreamResult result = new StreamResult(System.out);
webServiceTemplate.sendSourceAndReceiveToResult(source, result);
}
from http://docs.spring.io/spring-ws/site/reference/html/client.html and I got this excetion.
org.springframework.ws.soap.client.SoapFaultClientException: Operation 'message' is not defined in the WSDL for this service
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:37)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:774)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:600)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:492)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:436)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:427)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:417)
at Test.test1
How to fix it ?
Ok I solve it, in the question there is juste an exemple of a case where the error occured,
I used netcat as client and got this result:
POST / HTTP/1.1
Accept-Encoding: gzip
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.7.0_55
Host: localhost:1234
Connection: keep-alive
Content-Length: 154
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><message xmlns=\"http://tempuri.org\">Hello Web Service World</message></SOAP-ENV:Body></SOAP-ENV:Envelope>
In this test the message was not what the server was expecting. But I understood the problem.
I thought that spring ws wasn't creating the soap envelope, so the message had two envelopes.

Categories