Here is the problem...
I have a webservice which works great with the JAVA code...
package com.mypackage.myproject;
public class ExecuteGetOrder {
public static void main(String [ ] args)
{
try {
runGetOrder();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void runGetOrder() throws Exception
{
GetOrderDataInterface data = new GetOrderDataInterfaceProxy().getGetOrderDataInterface();
((org.apache.axis.client.Stub)data)._setProperty(org.apache.axis.client.Call.USERNAME_PROPERTY, "ent=,user=UserName");
((org.apache.axis.client.Stub)data)._setProperty(org.apache.axis.client.Call.PASSWORD_PROPERTY, "password");
String RtrnDataXML = data.OrderInfo("OrderNumber");
System.out.println(RtrnDataXML);
}
}
The Raw request looks like this...
POST http://win-bpqhaq6l0jt:8008/oms/services/GetOrderData HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: win-bpqhaq6l0jt:8008
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 366
Authorization: Basic ZW50PSx1c2VyPUEyTENNQWRtaW46cGFzc3dvcmQ=
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ammoOrderInfo xmlns="http://a2lcm.rhinotechnology.com/"><order xmlns="">OrderNumber</order></OrderInfo></soapenv:Body></soapenv:Envelope>
Now I want to do this same thing in a VB.NET windows application. First I added the service reference, but when I try to use the class generated with this code...
Dim OrderService As getOrderData.GetOrderDataInterfaceClient = New getOrderData.OrderDataInterfaceClient()
Dim returnedXMl = OrderService.OrderInfo("Order")
I get back this...
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic host=10.20.100.7
Content-Type: text/html;charset=utf-8
Content-Length: 948
Date: Fri, 30 May 2014 21:25:05 GMT
<html><head><title>JBossWeb/2.0.1.GA - Error report</title><style><!--H1 {font- family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font- family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p> <b>description</b> <u>This request requires HTTP authentication ().</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.1.GA</h3></body></html>
So the question is how do I set the HTTP Authorization: on the request when made with...
Dim OrderService As getOrderData.GetOrderDataInterfaceClient = New GetOrderData.OrderDataInterfaceClient()
Dim returnedXMl = OrderService.OrderInfo("Order")
So the solution for all trying to Basic authenticate with JBoss web services...
1) Add the following class (Code in vb)
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Description
Imports System.ServiceModel.Configuration
Imports System.Configuration
Public Class HttpUserAgentMessageInspector
Implements IClientMessageInspector
Private Const USER_AGENT_HTTP_HEADER As String = "Authorization"
Private m_userAgent As String
Public Sub New(ByVal userAgent As String)
MyBase.New()
Me.m_userAgent = userAgent
End Sub
Public Sub AfterReceiveReply(ByRef reply As System.ServiceModel.Channels.Message, ByVal correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
End Sub
Public Function BeforeSendRequest(ByRef request As System.ServiceModel.Channels.Message, ByVal channel As System.ServiceModel.IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
Dim httpRequestMessage As HttpRequestMessageProperty
Dim httpRequestMessageObject As Object
If request.Properties.TryGetValue(HttpRequestMessageProperty.Name, httpRequestMessageObject) Then
httpRequestMessage = CType(httpRequestMessageObject, HttpRequestMessageProperty)
If String.IsNullOrEmpty(httpRequestMessage.Headers(USER_AGENT_HTTP_HEADER)) Then
httpRequestMessage.Headers(USER_AGENT_HTTP_HEADER) = Me.m_userAgent
End If
Else
httpRequestMessage = New HttpRequestMessageProperty
httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, Me.m_userAgent)
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage)
End If
Return Nothing
End Function
End Class
Public Class HttpUserAgentEndpointBehavior
Implements IEndpointBehavior
Private m_userAgent As String
Public Sub New(ByVal userAgent As String)
MyBase.New()
Dim headerBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(userAgent)
Dim headerValue As String = ("Basic " + Convert.ToBase64String(headerBytes))
Me.m_userAgent = headerValue
End Sub
#Region "IEndpointBehavior Members"
Public Sub AddBindingParameters(ByVal endpoint As ServiceEndpoint, ByVal bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(ByVal endpoint As ServiceEndpoint, ByVal clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
Dim inspector As HttpUserAgentMessageInspector = New HttpUserAgentMessageInspector(Me.m_userAgent)
clientRuntime.MessageInspectors.Add(inspector)
End Sub
Public Sub ApplyDispatchBehavior(ByVal endpoint As ServiceEndpoint, ByVal endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
End Sub
Public Sub Validate(ByVal endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
End Sub
#End Region
End Class
Public Class HttpUserAgentBehaviorExtensionElement
Inherits BehaviorExtensionElement
Public Overrides ReadOnly Property BehaviorType As Type
Get
Return GetType(HttpUserAgentEndpointBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New HttpUserAgentEndpointBehavior(UserAgent)
End Function
<ConfigurationProperty("userAgent", IsRequired:=True)> _
Public Property UserAgent As String
Get
Return CType(Me("userAgent"), String)
End Get
Set(value As String)
Me("userAgent") = value
End Set
End Property
End Class
2) Add the following XML code to your app.config between the system.serviceModel tags.
<behaviors>
<endpointBehaviors>
<behavior name="LegacyServiceEndpointBehavior">
<httpUserAgent userAgent="[[[myusername:password]]]" />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="httpUserAgent" type=" [[[myNamespace]]].HttpUserAgentBehaviorExtensionElement, [[[myProjectName]]], Version=1.0.0.0, Cultu re=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
3) Change the highlighted text to your namespace and project respectively.
4) Add the following text surrounded by [[[ ]]]to the end of the endpoint address. This part will need done to each service.
<endpoint address="http://[[[ipAddress]]]/Location/GetOrderData"
binding="basicHttpBinding" bindingConfiguration="RLCM.GetOrderDataInterfaceSoapBinding"
contract="getOrderData.GetOrderDataInterface" name="GetOrderDataImplPort" [[[behaviorConfiguration="LegacyServiceEndpointBehavior"]]]/>
5) Now you should be able to use the code like this…
Dim OrderService As getOrderData.GetOrderDataInterfaceClient = New getOrderData.GetOrderDataInterfaceClient()
Dim returnedXML = OrderService.orderInfo("OrderNumber") and be authorized by the JBoss server and get back return data.
Related
I am consuming SOAP service where sending request to soap url and getting the response. But when i try to connect using WebServiceTemplate getting a nested exception as
com.sun.xml.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
Below is the code where i am sending the request to soap client
soapClient.sendEmail(request); - From the service to soap client
Below is the soap client code to connect and send the request
#Service
public class SoapClient {
#Autowired
private Jaxb2Marshaller marshaller;
private WebServiceTemplate template;
#Value("${email.url}")
String emailUrl;
#Value("${email.vaultQuery}")
String querytaken;
#Value("${email.valtQu}")
String queryp;
public MessageResponse sendEmail(MessageRequest request) {
template = new WebServiceTemplate(marshaller);
String plainCredentials = querytaken + ":" + queryp;
String base64Credentials = new String(Base64.encodeBase64(plainCredentials.getBytes()));
return (MessageResponse) template.marshalSendAndReceive(emailUrl, request,new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpUrlConnection connection = (HttpUrlConnection) context.getConnection();
connection.getConnection().setRequestProperty("Authorization", "Basic " + base64Credentials);
}
});
}
}
Can anyone help me out for my issue
When the service is being called by using method as GET, it works smoothly i.e. request.getParameter("userValue") is printed.
But while using Post method, it prints null for request.getParameter("userValue").
HTML code : (jsonObject has valid json)
var myData = "userValue=" + jsonObject ;
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Webservice_JS_26Oct/FieldsToFile/write",
data: myData,
contentType: "application/json; charset=utf-8",
dataType: "json",
Java Code:
#RequestMapping(value = "/FieldsToFile")
public class FileWriter {
#RequestMapping(value = "/write", method = RequestMethod.POST, produces = "application/json")
public String getData(HttpServletRequest request) throws IOException, IllegalStateException, ServletException {
String jsonString = request.getParameter("userValue") ;
System.out.println("jsonString = " + jsonString);
String myData = request.getParameter("myData") ;
I am new to this, Please advise how to make it work for POST method.
You can use request.getInputStream() to print the request body part. I suggest that your contentType: "application/json; charset=utf-8", can be application/x-www-form-urlencoded or HttpServletRequest request can be #Requestbody ..
I can request an API method via http://requestmaker.com/ using GET, but when I use POST or PUT it returns...
HTTP/1.1 403 Forbidden
Here is the method...
[HttpPost]
[Route("api/sales")]
public object Put([FromBody] Sale sale)
{
sale.DateTime = DateTime.Now;
paymentRepository.Insert(sale);
paymentRepository.Save();
return Ok(new { id = sale.SaleId });
}
Any ideas?
Request headers are...
POST /admin/api/sales HTTP/1.1 Host: hello.com Accept: /
Content-Type: text/html Content-Length: 17
Request data...
TourId=3&UserId=1
It has to do with how your Controller is routing the requests. You seem to have defined something like this
Defaults To GET:
public async Task<IHttpActionResult> MethodName(){
return this.Ok()
}
or
[HttpGet]
public async Task<IHttpActionResult> MethodName(){
return this.Ok()
}
There should be some attributes that you can define above the function:
For POST:
[HttpPost]
public async Task<IHttpActionResult> MethodNamePost(){
return this.Ok()
}
For PUT:
[HttpPut]
public async Task<IHttpActionResult> MethodNamePut(){
return this.Ok()
}
Like Win said:
[HttpPut]
[Route("api/sales")]
public object Put([FromBody] Sale sale)
{
sale.DateTime = DateTime.Now;
paymentRepository.Insert(sale);
paymentRepository.Save();
return new { id = sale.SaleId };
}
I would change the return to this.Ok(new {id = sale.SaleId}); though.
Your Request headers are wrong it should be like
{
"UserId":"1",
"TourID":"3",
}
REASON:application/json
Oh silly me, it was looking for an anti-forgery token. I thought I'd commented the filter out, but I'd done it for MVC and not Web Api. Oops.
I also needed to set the content type to application/json and set the data as { "TourId":"3", "UserId":"1" } in order for model binding to work.
Can someone help on this?
I am getting the below exception(org.springframework.web.HttpMediaTypeNotSupportedException) when I run this test.
In the response I get this Headers.
Headers = {Accept=[application/octet-stream, text/plain;charset=ISO-8859-1, application/xml, text/xml, application/x-www-form-urlencoded, application/+xml, multipart/form-data, application/json;charset=UTF-8, application/+json;charset=UTF-8, /]}
The add method in the controller is
#RequestMapping(value = "/addTrain", method = RequestMethod.POST)
public #ResponseBody void addTrain(#RequestBody Train train) {
trainService.addTrain(train);
}
I am doing JUnit test for a method. Below is my Test class and MockHttpServletRequest and MockHttpSErvletResponse.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:/config/webapp-config.xml" })
#WebAppConfiguration
public class TrainControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext wac;
#InjectMocks
TrainController trainController;
#Mock
private TrainService trainService;
private final List<Train> trainList = new ArrayList<Train>();
private Train train;
#Before
public void setUp() throws Exception {
// Process mock annotations
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
train = new Train();
train.setId(12L);
train.setName("chennai");
train.setSpeed(100);
train.setDiesel(true);
Train train1 = new Train();
train1.setId(15L);
train1.setName("kovai");
train1.setSpeed(150);
train1.setDiesel(false);
trainList.add(train);
trainList.add(train1);
}
#Test
public void testAddTrainList() throws Exception {
Mockito.doNothing().when(trainService).addTrain(train);
this.mockMvc.perform(post("/trains/addTrain")).andDo(print()).andExpect(status().isOk());
}
}
The request and reponse are below:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /trains/addTrain
Parameters = {}
Headers = {}
Handler:
Type = com.xvitcoder.angualrspringapp.controller.TrainController
Method = public void com.xvitcoder.angualrspringapp.controller.TrainController.addTrain(com.xvitcoder.angualrspringapp.beans.Train)
Async:
Was async started = false
Async result = null
**Resolved Exception:
Type = org.springframework.web.HttpMediaTypeNotSupportedException**
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
**MockHttpServletResponse:
Status = 415
Error message = null**
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Your request has to specify the Content-type header from one of the acceptable ones.
Try changing your mock request as below:
this.mockMvc.perform(post("/trains/addTrain").contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk());
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException
I want to implement basic authentication using username and password validation in my asmx web service.
I don't want to use WCF and I know this is not secure way, but I need to use basic authentication without using https.
My web service is like this:
[WebService(Namespace = "http://www.mywebsite.com/")]
public class Service1
{
[WebMethod]
public string HelloWorld()
{
return "Hello world";
}
}
And I use this custom HttpModule:
public class BasicAuthHttpModule : IHttpModule
{
void IHttpModule.Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(OnAuthenticateRequest);
}
void OnAuthenticateRequest(object sender, EventArgs e)
{
string header = HttpContext.Current.Request.Headers["Authorization"];
if (header != null && header.StartsWith("Basic")) //if has header
{
string encodedUserPass = header.Substring(6).Trim(); //remove the "Basic"
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string userPass = encoding.GetString(Convert.FromBase64String(encodedUserPass));
string[] credentials = userPass.Split(':');
string username = credentials[0];
string password = credentials[1];
if(!MyUserValidator.Validate(username, password))
{
HttpContext.Current.Response.StatusCode = 401;
HttpContext.Current.Response.End();
}
}
else
{
//send request header for the 1st round
HttpContext context = HttpContext.Current;
context.Response.StatusCode = 401;
context.Response.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", string.Empty));
}
}
void IHttpModule.Dispose()
{
}
}
And in the web.config I use this:
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.0"/>
<authentication mode="None"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="BasicAuthHttpModule"
type="AuthService.BasicAuthHttpModule, AuthService" />
</modules>
</system.webServer>
</configuration>
The calling code is:
static void Main(string[] args)
{
var proxy = new Service1.Service1()
{
Credentials = new NetworkCredential("user1", "p#ssw0rd"),
PreAuthenticate = true
};
try
{
var result = proxy.HelloWorld();
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
when I use this web service, the service asks for basic authentication but header variable in the OnAuthenticateRequest method always is null and MyUserValidator.Validate() never run.
EDIT
The fiddler results:
POST http://www.mywebsite.com/Service1.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.4927)
VsDebuggerCausalityData: uIDPo+drc57U77xGu/ZaOdYvw6IAAAAA8AjKQNpkV06FEWDEs2Oja2C+h3kM7dlDvnFfE1VlIIIACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.mywebsite.com/HelloWorld"
Host: www.mywebsite.com
Content-Length: 291
Expect: 100-continue
Connection: Keep-Alive
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorld xmlns="http://www.mywebsite.com/" /></soap:Body></soap:Envelope>
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
WWW-Authenticate: Basic realm=""
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Basic realm="www.mywebsite.com"
X-Powered-By: ASP.NET
Date: Sun, 03 Jun 2012 07:14:40 GMT
Content-Length: 1293
------------------------------------------------------------------
POST http://www.mywebsite.com/Service1.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.4927)
VsDebuggerCausalityData: uIDPo+drc57U77xGu/ZaOdYvw6IAAAAA8AjKQNpkV06FEWDEs2Oja2C+h3kM7dlDvnFfE1VlIIIACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.mywebsite.com/HelloWorld"
Authorization: Basic dXNlcjE6cEBzc3cwcmQ=
Host: www.mywebsite.com
Content-Length: 291
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorld xmlns="http://www.mywebsite.com/" /></soap:Body></soap:Envelope>
HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/7.5
WWW-Authenticate: Basic realm="www.mywebsite.com"
X-Powered-By: ASP.NET
Date: Sun, 03 Jun 2012 07:14:41 GMT
Content-Length: 1293
------------------------------------------------------------------
Change your custom HttpModule code to this:
public class BasicAuthHttpModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication application)
{
application.AuthenticateRequest += new
EventHandler(this.OnAuthenticateRequest);
application.EndRequest += new
EventHandler(this.OnEndRequest);
}
public void OnAuthenticateRequest(object source, EventArgs
eventArgs)
{
HttpApplication app = (HttpApplication)source;
string authHeader = app.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
string authStr = app.Request.Headers["Authorization"];
if (authStr == null || authStr.Length == 0)
{
return;
}
authStr = authStr.Trim();
if (authStr.IndexOf("Basic", 0) != 0)
{
return;
}
authStr = authStr.Trim();
string encodedCredentials = authStr.Substring(6);
byte[] decodedBytes =
Convert.FromBase64String(encodedCredentials);
string s = new ASCIIEncoding().GetString(decodedBytes);
string[] userPass = s.Split(new char[] { ':' });
string username = userPass[0];
string password = userPass[1];
if (!MyUserValidator.Validate(username, password))
{
DenyAccess(app);
return;
}
}
else
{
app.Response.StatusCode = 401;
app.Response.End();
}
}
public void OnEndRequest(object source, EventArgs eventArgs)
{
if (HttpContext.Current.Response.StatusCode == 401)
{
HttpContext context = HttpContext.Current;
context.Response.StatusCode = 401;
context.Response.AddHeader("WWW-Authenticate", "Basic Realm");
}
}
private void DenyAccess(HttpApplication app)
{
app.Response.StatusCode = 401;
app.Response.StatusDescription = "Access Denied";
app.Response.Write("401 Access Denied");
app.CompleteRequest();
}
}
Then enable Anonymous authentication and disable Basic, Digest and Windows authentication for your website in IIS.
Note: This implementation will work with WCF too.
It seems that you need send the headers manually the first time:
from Rick Strahl's Blog
string url = "http://rasnote/wconnect/admin/wc.wc?_maintain~ShowStatus";
HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;
string user = "ricks";
string pwd = "secret";
string domain = "www.west-wind.com";
string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(user + ":" + pwd));
req.PreAuthenticate = true;
req.Headers.Add("Authorization", auth);
req.UserAgent = ": Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 4.0.20506)";
WebResponse resp = req.GetResponse();
resp.Close();