Showing posts with label wcf. Show all posts
Showing posts with label wcf. Show all posts

Saturday, June 30, 2018

Cannot support both http and https url when running a ServiceHost

Leave a Comment

I'm trying to enable exposing a ServiceHost on both HTTP & HTTPS.

Here is the code that runs the service:

oServiceHost = new ServiceHost(typeof(API), new Uri(WebHookURL)) oServiceHost.Open(); 

As you can see here - I'm getting the service URL (WebHookURL) during runtime. As mentioned, URL protocol can be either HTTP or HTTPS.

After lots of reading and testing, it came down to this web.config file:

 <system.serviceModel>     <client>       <endpoint binding="customBinding" bindingConfiguration="encryptingBinding" contract="ModuleComm.Commons.ServiceContracts.ModuleService" name="clientConf" />     </client>     <services>       <service name="myServiceWebServer.AsynchronousSocketListener">         <endpoint binding="customBinding" bindingConfiguration="encryptingBinding" contract="ModuleComm.Commons.ServiceContracts.ModuleService" />       </service>       <service behaviorConfiguration="API.Service1Behavior" name="myServiceWebServer.API">         <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="myServiceWebServer.IAPI" />         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />       </service>     </services>     <behaviors>       <serviceBehaviors>         <behavior name="API.Service1Behavior">           <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />           <serviceDebug includeExceptionDetailInFaults="False" />         </behavior>       </serviceBehaviors>       <endpointBehaviors>         <behavior name="web">           <webHttp />                 </behavior>       </endpointBehaviors>     </behaviors>     <bindings>       <customBinding>         <binding name="encryptingBinding">           <!--  <messageEncryping /> -->           <textMessageEncoding>             <readerQuotas maxStringContentLength="2147483647" />           </textMessageEncoding>           <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">             <connectionPoolSettings leaseTimeout="23:59:00" maxOutboundConnectionsPerEndpoint="10000" />           </tcpTransport>         </binding>       </customBinding>       <webHttpBinding>         <binding name="webBinding">           <security mode="Transport">             <transport clientCredentialType="None"/>           </security>         </binding>       </webHttpBinding>     </bindings>     <protocolMapping>       <add binding="webHttpBinding" bindingConfiguration="webBinding" scheme="https" />     </protocolMapping>   </system.serviceModel> 

When trying to set WebHookURL (e.g: http://localhost:8111) to an http address - code works fine.

Unfortunately, when setting WebHookURL to an https address (e.g: https://localhost:8111) - code won't work and this exception is thrown when trying to create the ServiceHost instance:

Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https]. 

What am I missing ?

UPDATE 1:

Tried this configurations but i'm getting configuration error: Tried this but i'm getting configuration error:

<system.serviceModel>     <services>             <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API">         <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" />         <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" />         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />       </service>     </services>     <behaviors>       <serviceBehaviors>         <behavior name="API.Service1Behavior">           <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />           <serviceDebug includeExceptionDetailInFaults="False" />         </behavior>       </serviceBehaviors>       <endpointBehaviors>         <behavior name="web">           <webHttp />                 </behavior>       </endpointBehaviors>     </behaviors>     <bindings>             <wsHttpBinding>                 <binding name="webBinding">           <security mode="None">             <transport clientCredentialType="None"/>           </security>         </binding>         <binding name="wsBindingHTTPS">           <security mode="Transport">             <transport clientCredentialType="None"/>           </security>         </binding>       </wsHttpBinding>     </bindings>   </system.serviceModel> 

4 Answers

Answers 1

the problem is here:

   <webHttpBinding>         <binding name="webBinding">           <security mode="Transport">             <transport clientCredentialType="None"/>           </security>         </binding>       </webHttpBinding> 

The webHttpBinding supports only HTTP requests and not HTTPS requests. webHttpBinding does not support interoperability as well.

WsHttpBinding also supports interoperability. With this binding, the SOAP message is, by default, encrypted. It supports HTTP and HTTPS. In terms of encoding, it provides support for Text as well as MTOM encoding methods. It supports WS-* standards like WS-Addressing, WS-Security and WS-ReliableMessaging. By default, reliable sessions are disabled because it can cause a bit of performance overhead. http://www.codeproject.com/Articles/431291/WCF-Services-Choosing-the-appropriate-WCF-binding

So in order to use https, replace webHttpBinding with WsHttpBinding.

Here is a snippet that will match your solution:

1) Write two endpoints for the service, one is for http and another for https.

<services>     <service behaviorConfiguration="MyServiceBehavior" name="JK.MyService">        <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="JK.IMyService">         <identity>           <dns value="localhost" />         </identity>       </endpoint>        <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBindingHTTPS" contract="JK.IMyService">         <identity>           <dns value="localhost" />         </identity>       </endpoint>           </service>   </services> 

2) Enable both httpGetEnabled="True" httpsGetEnabled="true" in serviceBehaviors.

<behaviors>  <serviceBehaviors>         <behavior name="MyServiceBehavior">     <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>     <serviceDebug includeExceptionDetailInFaults="true" />   </behavior>       </serviceBehaviors>  <endpointBehaviors>   <behavior name="WebBehavior">     <webHttp/>   </behavior> </endpointBehaviors>  </behaviors> 

3) Write two bindings configurations for http and https. For http give security mode="None" and for https give mode="Transport".

<bindings>     <wsHttpBinding>        <binding name="webBinding">         <security mode="None">           <transport clientCredentialType="None" />         </security>       </binding>        <binding name="webBindingHTTPS">         <security mode="Transport">           <transport clientCredentialType="None" />         </security>       </binding>      </wsHttpBinding>   </bindings> 

Check this link

Answers 2

<services>         <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API">     <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" />     <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" />     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />   </service> </services> 

In the endpoints defined in the configuration above, the value for binding is specified as webHttpBinding. However, the configuration provided for those bindings are defined for wsHttpBinding. Clearly there is a mismatch between the type of binding and its configuration. The below change should fix this error.

<services>         <service behaviorConfiguration="API.Service1Behavior" name="WebServer.API">     <endpoint address="" behaviorConfiguration="web" binding="wsHttpBinding" bindingConfiguration="webBinding" contract="WebServer.IAPI" />     <endpoint address="" behaviorConfiguration="web" binding="wsHttpBinding" bindingConfiguration="wsBindingHTTPS" contract="WebServer.IAPI" />     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />   </service> </services> 

Also in the below snippet, the transport element is redundant since the security mode is None and hence can be removed.

<binding name="webBinding">   <security mode="None">     <transport clientCredentialType="None"/>   </security> </binding> 

Answers 3

Here is another idea: Why not allow HTTPS requests ONLY and re-route http request into https request. If your web server has IIS then you may find this useful

and bar http request can be done like

we generally apply certificate on NLB Node(Network Load Balanced) and configure http to https route on all individual web servers

Answers 4

actually its simple. all you need is one binding for http and another one for https like this:

<bindings>  <basicHttpBinding>     <binding name="SoapBinding"  />  </basicHttpBinding>  <mexHttpBinding>     <binding name="MexBinding" />  </mexHttpBinding>  <mexHttpsBinding>     <binding name="SecureMexBinding" />  </mexHttpsBinding>  <basicHttpsBinding>     <binding name="SecureSoapBinding"  />  </basicHttpsBinding>  <webHttpBinding>     <binding name="RestBinding"  />     <binding name="SecureRestBinding" >      <security mode="Transport" />     </binding>  </webHttpBinding> </bindings>     <services>         <service behaviorConfiguration="ServiceBehavior" name="myServiceWebServer.API">             <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="SoapBinding" name="Soap" contract="myServiceWebServer.IAPI" />             <endpoint address="soap" binding="basicHttpsBinding" bindingConfiguration="SecureSoapBinding" name="SecureSoap" contract="myServiceWebServer.IAPI" />             <endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="RestBinding" name="Rest" contract="myServiceWebServer.IAPI" />             <endpoint address="" behaviorConfiguration="Web" binding="webHttpBinding" bindingConfiguration="SecureRestBinding" name="SecureRest" contract="myServiceWebServer.IAPI" />             <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="MexBinding" name="Mex" contract="IMetadataExchange" />             <endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="SecureMexBinding" name="SecureMex" contract="IMetadataExchange" />         </service>     </services> 
Read More

Tuesday, February 20, 2018

View Complete WCF response on error using Visual Studio 2010

Leave a Comment

In Visual Studio 2010 I get an error which tells me the first 1024 bytes of a response from a WCF service when consumed, but no more.

I would really like to see the entire response so I can work out what is going wrong, where can I get this info from? Is there a way of logging the full text of an error or are they all limited by the 1024 byte rule?

How to View more than 1024 bytes of a wcf response when an error occurs in Visual Studio 2010?

2 Answers

Answers 1

If you are doing this in debugging mode, where you have the exact steps pre-identified - you could try if setting maxReceivedMessageSize to a large value helps.

As the description says on the docs:

maxReceivedMessageSize

A positive integer that specifies the maximum message size, in bytes, including headers, that can be received on a channel configured with this binding. The sender of a message exceeding this limit will receive a SOAP fault. The receiver drops the message and creates an entry of the event in the trace log. The default is 65536.

In your case, it might have been set to a lower value.

You could also check if the maxBufferPoolSize has been set correctly - it seems that only one buffer worth of 1024 bytes are being transmitted back, which is possible if someone set the pool size as 1 instead of default 512.

Answers 2

Updated:

Use SvcConfigEditor.exe tool for tracing and logging need to be enabled in WCF configuration (app.config or web.config). Or you can use this SvcTraceViewer.exe tool for viewing the large XML's file.

For instance, you can below web.config settings for initializeData attribute of the tracelistener.

<system.serviceModel>     <diagnostics>         <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />     </diagnostics> </system.serviceModel> <system.diagnostics>     <sources>         <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">             <listeners>                 <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\SvcLog\Traces.svclog" />             </listeners>         </source>     </sources> </system.diagnostics> 
Read More

Sunday, February 11, 2018

Application Architecture - Monolith to Distributed/SOA

Leave a Comment

I have experience creating web applications using MS Asp.Net Stack (Asp.Net MVC / Web API), using 3-tier architecture (Monoliths)

I want to learn how to make applications scalable and maintainable, and want to clarify certain confusions with buzz-words.

  1. Distributed vs. SOA - I believe a scalable/maintainable application means segregating service layers (persistence, security, caching, etc.), and moving them to separate tiers. This is advocated by both distributed and SOA, so what's the difference b/w two?
  2. Service implementation, deployment and management - How to do it practically? I sense 2 types of services exist - Active and Passive.
  3. Passive Services - These kinds of services are essentially functions/methods that can be called to perform some operation. They can be implemented as WCF or Web API. With say 10 such services in hand, how do we implement, deploy (host) and manage them? How to know if any of service host goes down or malfunctions?
  4. Active Services - These kinds of services are active executables, and might be listening to a message-broker to fetch queued work. So, again, with say 10 such services in hand, how do we implement, deploy (host) and manage them? Do we create separate window services for each?
  5. Service Communication - with services segregated to different tiers, how to decide if they should communicate synchronously (web api) or asynchronously through message-broker (pub-sub)?

2 Answers

Answers 1

Here my perspective. Before I get to your questions let me address the general conception of monolith vs microservice: The difference lies in how the code is separated and what the goal is. For a monolith you try to apply techniques that aim to make it possible for a very large team (say 100s of engineers) to work on a single code base for an application. This means the introduction of layers and a lot of abstraction work typically to separate modules. And sometimes there is a lot of over-engineering in the design to promote reuse and separate layers at the same time. Usually it is easy for new employees to mess something up or not adhere to the complex architecture. Additionally there is often a large graph of dependencies between modules. The microservices philosophy now comes and tries to enforce modularity by having separate teams responsible for different services and not allowing them to share data persistency. In other words it tries to address the issues stemming from "Architecture follows Organization" (Conway's Law) by organizing teams by architecture and not the other way round. From my personal experience this is very fundamental to many issues in large organizations developing software and something that people often misunderstand when someone uses the buzzword microservices. For more information I recommend reading the works of Fowler. So the technology (.Net, Java, golang, etc.) does not play as much a role and the traditional "tiering" of services is an architectural decision that is still relevant but has to be seen less from a perspective of monolithic tiers but rather as tiers of clustered, scalable services (more about that below).

So now to your questions:

  1. Distributed vs. SOA: These are different viewing angles onto architecture and only intersect with the difference of monolith vs microservices in that a distributed architecture promotes techniques that are relevant for the devops required to build, test, deploy and scale (micro)services. And a SOA does not imply a monolith or microservices in itself. Simplified it just promotes the usage of clearly defined APIs and standardization of communication protocols between services. Some people also imply self-containment, which in this case the overlap to the microservices intention is larger. But others call the front services that their monolith provides also SOA. So you always have to look into the details.

  2. Service implementation, deployment and management. Beside the buzzwords there are a few actually useful techniques that are relevant here: Containerized applications (see Docker), which then enable clustered, orchestrated deployment (see kubernetes), which in combination with stateless application containers allow seamless scalability of services (see auto-scaling). Additionally scalable databases are coming more and more into the picture (see cockroachdb and various NoSQLs). And everything can be automated / tested / controlled from CICD servers (continuous integration / continuous deployment) - See Jenkins for example. All these make large application deployments so much easier and also allow for zero-outage updates if done right (see the topic of rolling updates). A cluster system will also typically contain functionality to detect the application health (for example endpoint testing). Unhealthy containers can be excluded from servicing client requests and replaced in an automated fashion by the container orchestration system.

  3. and

  4. Active/Passive Services: This distinction is not quite as useful. In the world of clusterized applications you think of each deployed application as a server providing services (usually formalized in a deployment description) or as a simple task/workload without services. But each may have dependencies to the outside world. In other words each deployed application could be active/passive or both but all will have some executable portion. I recommend looking into how a deployment is formalized with kubernetes for example.

  5. Communication: Typically most communication will be asynchronous with the caveat that the service implemention often includes techniques to allow for treating an asynchronous call almost as if it was synchronous in the code (e.g. promises, observables). This is due to the fact that humans cannot think asynchronously very well.

Let me know if that answers some of your questions or if it only adds to the confusion.

Answers 2

Some of the very basic requirement for transitioning a monolith service to a distributed service is:

Get rid of the state in your application. By this I mean you should avoid having static fields & any information which is restricted to a single JVM. Rather move out all the information which specific servers are holding to a central memory like HazelCast or Memcache. So that all your servers share common information. This will enable your app to be consistent when any of your server goes down.

The same rule holds good when using sessions. Move all the sessions to a central memory.

P.S. I work on Java Stack so you can look for similar .NET tech.

Moving down to your questions

  1. Distributed vs. SOA : The difference between the two is very subtle. A Service Oriented Architecture means there are several independent services running with respective responsibilities. They are all components of a single application. Read about Web Services. For an instance Billing can be one service. Booking Tickets can be another service working in conjunction. SOA makes the system more manageable.

Distributed means splitting/partitioning a service into multiple chunks to achieve scalability & availability. Now this concept can be applied both at a higher level or on individual services in the SOA. The service runs on several nodes/servers. If one node goes down the entire Billing service doesn't go down.

  1. Service implementation, deployment and management: A distributed system ideally runs on cloud. Go through Google Cloud & Amazon Cloud docs. You'll get an understanding how the entire flow works. Also read about SQL vs NOSQL. CAP Theorem. ACID vs BASE. Can't write everything here. The answer will become humongous.

  2. Active/Passive Services: Stated above cloud docs. will help you get an understanding about these services. Also look into Zookeeper.

  3. Service Communication: Communicating synchronously or asynchronously entirely depends upon the application design. You would require a messaging service like RabbitMQ or Kafqa if you are communicating with other services.

You have a lot to read. GoodLuck :)

Read More

Wednesday, January 10, 2018

How to integrate LDAP in WPF application that consumes WCF service

Leave a Comment

I will start by describing how my application works today without LDAP. I have WPF application that consumes WCF services (authentication windows or UserName depends on users choice). This services allows communication with database.

I display to user a "Login screen" in order to allow him set her "user name" and "password" then application connects to service and consumes function that checks if UserName and Password exist in database. (see img below) enter image description here

Now I need also to integrate LDAP for authenticating user accounts against their existing systems instead of having to create another login account.

I'm bit ignorant about LDAP and confused about many things. Please excuse the possible use of wrong terminology.

I googled but I still don't have answers of many questions.

1- What is the relation between users that exist in my database table "User" and profiles that I should be created in LDAP ?

2- What is the check I should do to allow user come from LDAP to access to my application and use all functionnalities of my service ?

3- Should I have service type "LDAP" like other authentications types I have today in my application ("Windows" and "UserName") ?

4- If I want to update my application architecture described in picture above where should I add LDAP ?

1 Answers

Answers 1

Let me tell you about my experience in LDAP and Authenticate users on LDAP or DB,

I also implemented a service named Auth.svc, this service contains a method named AuthenticateAndAuthorizedUser , this is transparent for user which came from LDAP or anywhere.

1- In the other words I have a table named Users which hold users infos and one more field named ExternalPath foreign key, if it is null then UserName is in DB otherwise it is came from UserDirectory.

2- You have to hold LDAP address (in my case LDAP addresses are in ExternalPath table), All LDAP addresses are on port 389 commonly.

3- Authenticate User if is not found(with Username and Password) then Verify it over LDAP address.

4- Let me share my DB schema and Authenticate Method.

enter image description here

ExternalPath field specify user is from LDAP or not.

5- Define LDAP server and User...

enter image description here

6- While adding new user you can define LDAP for user (if you select LDAP address then don't need to get password from user)

7- But last thing is Authenticating user on LDAP and DB.

Authenticate Method is something like:

User userLogin = User.Login<User>(username, password, ConnectionString, LogFile); if (userLogin != null)     return InitiateToken(userLogin, sourceApp, sourceAddress, userIpAddress); else//Check it's LDAP path {     User user = new User(ConnectionString, LogFile).GetUser(username);     if (user != null && user.ExternalPath != null)     {         LDAPSpecification spec = new LDAPSpecification         {             UserName = username,             Password = password,             Path = user.ExternalPath.Path,             Domain = user.ExternalPath.Domain         };         bool isAthenticatedOnLDAP = LDAPAuthenticateUser(spec);      } } 

If userLogin does not exist in DB by entered UserName and Pass then we should authenticated it over related LDAP address.

First find User and Get it's ExternalPath if not null means User is on LDAP.

so the LDAPAuthenticateUser method is :

public bool LDAPAuthenticateUser(LDAPSpecification spec) {     string pathDomain = string.Format("LDAP://{0}", spec.Path);     if (!string.IsNullOrEmpty(spec.Domain))         pathDomain += string.Format("/{0}", spec.Domain);     DirectoryEntry entry = new DirectoryEntry(pathDomain, spec.UserName, spec.Password, AuthenticationTypes.Secure);     try     {         //Bind to the native AdsObject to force authentication.         object obj = entry.NativeObject;         DirectorySearcher search = new DirectorySearcher(entry);          search.Filter = "(SAMAccountName=" + spec.UserName + ")";         search.PropertiesToLoad.Add("cn");         SearchResult result = search.FindOne();         if (null == result)         {             return false;         }     }     catch (Exception ex)     {         Logging.Log(LoggingMode.Error, "Error authenticating user on LDAP , PATH:{0} , UserName:{1}, EXP:{2}", pathDomain, spec.UserName, ex.ToString());         return false;     }     return true; } 

If exception raised in LDAPAuthenticateUser means User does not exist in User Directory.

Hope will help you.

Read More

Wednesday, December 27, 2017

WCF : The EncryptedKey clause was not wrapped with the required encryption token 'System.IdentityModel.Tokens.X509SecurityToken'

Leave a Comment

I'm trying to use WCF client to connect to Java based web services

Certificates I have been provided (self-signed) work perfectly in SOAPUI.

Here is my setup:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

However, I'm having problems using WCF client.

My app.config

    <bindings>       <customBinding>         <binding name="Example_TestBinding">                        <security defaultAlgorithmSuite="TripleDesRsa15"                      authenticationMode="MutualCertificate"                      requireDerivedKeys="false"                      includeTimestamp="false"                      messageProtectionOrder="SignBeforeEncrypt"                      messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"                      requireSignatureConfirmation="false">                             <localClientSettings detectReplays="true"/>             <localServiceSettings detectReplays="true"/>                           </security>                         <textMessageEncoding messageVersion="Soap11"/>                        <httpsTransport authenticationScheme="Basic" manualAddressing="false" maxReceivedMessageSize="524288000" transferMode="Buffered"/>                     </binding>       </customBinding>     </bindings>   <client>     <endpoint        address="https://blabla.hana.ondemand.com/Example_Test"        binding="customBinding"        bindingConfiguration="Example_TestBinding"        contract="WebServiceTest.Example_Test"        name="Example_Test"      />   </client> 

Using Keystore Explorer I export both certificates from JKS as:

  • public_test_hci_cert.cer
  • test_soap_ui.p12

Web service call:

            var client = new Example_TestClient();             client.ClientCredentials.UserName.UserName = "user";             client.ClientCredentials.UserName.Password = "pass";              X509Certificate2 certClient = new X509Certificate2(certClientPath, certClientPassword);             client.ClientCredentials.ClientCertificate.Certificate = certClient;              X509Certificate2 certService= new X509Certificate2(certServicePath);             client.ClientCredentials.ServiceCertificate.DefaultCertificate = certService;              var response = client.Example_Test(requestObj);   

The request arrives perfectly at the server but it seems that WCF doesn't understand the response since I get this exception:

"The EncryptedKey clause was not wrapped with the required  encryption token 'System.IdentityModel.Tokens.X509SecurityToken'."     at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)\r\n ... 

Service Trace gives:

The security protocol cannot verify the incoming message 

UPDATE1: simplified the task by using the same certificate for signing and encryption. Same message.

UPDATE2: I wrote CustomTextMessageEncoder where I manually decrypt the message body and it works. However returning it in ReadMessage still throws the error.

    public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)     {         var msgContents = new byte[buffer.Count];         Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);         bufferManager.ReturnBuffer(buffer.Array);         var message = Encoding.UTF8.GetString(msgContents);          //return ReadMessage(Decryptor.DecryptBody(message), int.MaxValue);         var stream = new MemoryStream(Encoding.UTF8.GetBytes(message));         return ReadMessage(stream, int.MaxValue);     }      public static MemoryStream DecryptBody(string xmlResponse)     {         X509Certificate2 cert = new X509Certificate2(clientCertPath, certPass);         SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();          XmlDocument xmlDoc = new XmlDocument();         xmlDoc.PreserveWhitespace = true;         xmlDoc.LoadXml(xmlResponse);          XmlElement encryptedKeyElement = xmlDoc.GetElementsByTagName("EncryptedKey", XmlEncryptionStrings.Namespace)[0] as XmlElement;         XmlElement keyCipherValueElement = encryptedKeyElement.GetElementsByTagName("CipherValue", XmlEncryptionStrings.Namespace)[0] as XmlElement;         XmlElement encryptedElement = xmlDoc.GetElementsByTagName("EncryptedData", XmlEncryptionStrings.Namespace)[0] as XmlElement;          var key = Convert.FromBase64String(keyCipherValueElement.InnerText);          EncryptedData edElement = new EncryptedData();         edElement.LoadXml(encryptedElement);         EncryptedXml exml = new EncryptedXml();          algorithm.Key = (cert.PrivateKey as RSACryptoServiceProvider).Decrypt(key, false);          byte[] rgbOutput = exml.DecryptData(edElement, algorithm);         exml.ReplaceData(encryptedElement, rgbOutput);          //var body = Encoding.UTF8.GetString(rgbOutput);          MemoryStream ms = new MemoryStream();         xmlDoc.Save(ms);         return ms;     }  

1 Answers

Answers 1

I left this problem for the final sprint in my project and finally got back to it.
It is certificate problem. The self-signed certificates I was provided by Java based web service was generated with KeyStore Explorer. Both certificates were missing an important part:

Subject Key Identifier 

enter image description here

Once regenerated WCF was able to decrypt it without using encoders.

Also I had to:

  1. Install service certificate in the Trusted Root CA (user)
  2. Set Web Services to reply with Timestamp

I removed all config from the code (except client username and password) and placed in the app.config. Here is the complete config:

  <system.serviceModel>       <bindings>           <customBinding>             <binding name="Example_TestBinding">                            <security                                                 defaultAlgorithmSuite="TripleDesRsa15"                          authenticationMode="MutualCertificate"                          requireDerivedKeys="false"                          includeTimestamp="true"                          messageProtectionOrder="SignBeforeEncrypt"                          messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"                          requireSignatureConfirmation="false"                         allowSerializedSigningTokenOnReply="true"                          >               </security>                             <textMessageEncoding messageVersion="Soap11"/>               <httpsTransport authenticationScheme="Basic"                                manualAddressing="false"                                maxReceivedMessageSize="524288000"                                transferMode="Buffered"/>                                       </binding>           </customBinding>          </bindings>       <client>         <endpoint address="https://klaatuveratanecto.com/cxf/Example_TestBinding"                   behaviorConfiguration="endpointCredentialBehavior"                   binding="customBinding"                    bindingConfiguration="Example_TestBinding"                    contract="WebServiceTest.Example_Test"                    name="Example_Test">           <identity>             <dns value="test.service.klaatuveratanecto.com"/>           </identity>         </endpoint>       </client>     <behaviors>       <endpointBehaviors>         <behavior name="endpointCredentialBehavior">           <clientCredentials>             <serviceCertificate>               <defaultCertificate findValue="test.service.klaatuveratanecto.com"                                storeLocation="CurrentUser"                                storeName="Root"                                x509FindType="FindBySubjectName" />             </serviceCertificate>             <clientCertificate findValue="test.client.klaatuveratanecto.com"                                storeLocation="CurrentUser"                                storeName="My"                                x509FindType="FindBySubjectName" />           </clientCredentials>         </behavior>       </endpointBehaviors>     </behaviors>   </system.serviceModel> 

How did I get there. Well looking at the stack trace:

Server stack trace:     at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)    at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)    at System.ServiceModel.Security.WSSecurityTokenSerializer.ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)    at System.IdentityModel.Selectors.SecurityTokenSerializer.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)    at System.ServiceModel.Security.WSSecurityOneDotZeroReceiveSecurityHeader.DecryptWrappedKey(XmlDictionaryReader reader)    at System.ServiceModel.Security.ReceiveSecurityHeader.ReadEncryptedKey(XmlDictionaryReader reader, Boolean processReferenceListIfPresent)    at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)    at System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)    at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)    at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message& message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)    at System.ServiceModel.Security.AsymmetricSecurityProtocol.VerifyIncomingMessageCore(Message& message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)    at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)    at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

I debugged CreateWrappedKeyToken method with help of JetBrains dotPeek and saw that it tries to read raw SKI from the certificate and it's not finding it.

Read More

Wednesday, October 25, 2017

Apache CXF Client for Microsoft WCF service with MTOM returning 400

Leave a Comment

I have an apache CXF client for a Microsoft WCF service, and I am attempting to send a file via MTOM. However, I keep getting a 400, and the error on the WCF side according to the partner is that there is an error creating the MTOM reader

I've traced the outbound message, and it looks like this:

INFO: Outbound Message --------------------------- ID: 1 Address: https://someserver.com/ImportService.svc?wsdl Encoding: UTF-8 Http-Method: POST Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f"; start="<root.message@cxf.apache.org>"; start-info="application/soap+xml; action=\"http://tempuri.org/IImportService/UploadFile\"" Headers: {Accept=[*/*], Accept-Encoding=[gzip;q=1.0, identity; q=0.5, *;q=0], Content-Encoding=[gzip]} Payload: --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f Content-Type: application/xop+xml; charset=UTF-8; type="application/soap+xml; action=\"http://tempuri.org/IImportService/UploadFile\"" Content-Transfer-Encoding: binary Content-ID: <root.message@cxf.apache.org>      <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">     <soap:Header>         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="true">             <wsse:UsernameToken wsu:Id="UsernameToken-e51a6fdd-5053-4aae-a9fb-363dde7d9e77">                 <wsse:Username>blah@test.com</wsse:Username>                 <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypassword</wsse:Password>             </wsse:UsernameToken>         </wsse:Security>         <ns2:letterOptions xmlns="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns2="http://tempuri.org/">             <EnableQBPlanConsolidation>false</EnableQBPlanConsolidation>             <MASKSSN>true</MASKSSN>             <SRPrintedNumberofDays>2</SRPrintedNumberofDays>             <SuppressAllLetters>false</SuppressAllLetters>             <SuppressNewMemberLoginLetter>false</SuppressNewMemberLoginLetter>             <SuppressTakeOverLetterForTermed>false</SuppressTakeOverLetterForTermed>             <SuppressTerminationLetter>false</SuppressTerminationLetter>         </ns2:letterOptions>         <ns2:JobQueueType xmlns="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns2="http://tempuri.org/">Import</ns2:JobQueueType>         <Filename xmlns="http://tempuri.org/">testImport.csv</Filename>         <Action xmlns="http://www.w3.org/2005/08/addressing">http://tempuri.org/IImportService/UploadFile</Action>         <MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:f380e4cc-225f-4b7d-bd46-6b5d607a59ca</MessageID>         <To xmlns="http://www.w3.org/2005/08/addressing">https://someserver.com/ImportService.svc?wsdl</To>         <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">             <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>         </ReplyTo>     </soap:Header>     <soap:Body>         <FileUploadMessage xmlns="http://tempuri.org/" xmlns:ns2="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/">             <FileByteStream>                 <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:68e0408d-81da-496b-a06c-24a0459207d1-1@tempuri.org"/>             </FileByteStream>         </FileUploadMessage>     </soap:Body> </soap:Envelope> --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f Content-Type: application/octet-stream Content-Transfer-Encoding: binary Content-ID: <68e0408d-81da-496b-a06c-24a0459207d1-1@tempuri.org>  [VERSION],1.0 [NPM],552652222,1,Basic Client,Basic Client,Bob,Z,Jones,MR,bjones@test.com,402444555,,1234 Some street,,Omaha,NE,68123,,M,T,F,F  --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f-- 

I've found plenty of other instances where other folks had the same issue: https://coderanch.com/t/224995/java/Apache-CXF-MTOM-enabled-WCF

HTTP Bad Request error when requesting a WCF service contract

http://mail-archives.apache.org/mod_mbox/cxf-users/201211.mbox/%3CCAPXLCrCLkSkC8dQFeuU8DLY6gne1SOhwT9eMDxAUxLudnqU+YA@mail.gmail.com%3E

None of these were able to resolve my issue. I've tried multiple different versions of CXF and I get the same error with all of them.

This is a consolidated version of the code that is calling the service:

    JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();     proxyFactory.setBindingId(SOAPBinding.SOAP12HTTP_MTOM_BINDING);     proxyFactory.setServiceClass(IImportService.class);     proxyFactory.setAddress(proxyEndpoint);     proxyFactory.getFeatures().add(new WSAddressingFeature());      IImportService importService = (IImportService) proxyFactory.create();      Client client = (Client) importService;      LetterOptions letterOptions = new LetterOptions();     letterOptions.setSRPrintedNumberofDays(2);     letterOptions.setMASKSSN(true);     letterOptions.setEnableQBPlanConsolidation(false);      List<Object> headerList = new ArrayList<>();      headerList.add(new Header(new QName("http://tempuri.org/", "letterOptions"),             letterOptions, new JAXBDataBinding(LetterOptions.class)));     headerList.add(new Header(new QName("http://tempuri.org/", "JobQueueType"), JobQueueType.IMPORT, new JAXBDataBinding(JobQueueType.class)));     headerList.add(new Header(new QName("http://tempuri.org/", "Filename"), "testImport.csv", new JAXBDataBinding(String.class)));      client.getRequestContext().put(Header.HEADER_LIST, headerList);     client.getEndpoint().getActiveFeatures().add(new LoggingFeature());      client.getInInterceptors().add(new GZIPInInterceptor());     client.getInInterceptors().add(new LogResponseInterceptor());      GZIPOutInterceptor outInterceptor = new GZIPOutInterceptor();     outInterceptor.setForce(true);     client.getOutInterceptors().add(outInterceptor);      Map props = new HashMap();     props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);     props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);     props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName());     props.put(WSHandlerConstants.USER, "blah@test.com");     WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);     client.getOutInterceptors().add(wssOut);      HTTPConduit conduit = (HTTPConduit) client.getConduit();     HTTPClientPolicy policy = conduit.getClient();     if(policy == null) {         policy = new HTTPClientPolicy();     }     policy.setAllowChunking(false);      FileUploadMessageReponse response = importService.uploadFile(fileUploadMessage); 

One interesting tidbit is that I can copy the same request that is being logged into SoapUI, and it works fine.

0 Answers

Read More

Thursday, October 19, 2017

Calling a WCF method in Excel switches “context” and lets Word continue “work”

Leave a Comment

My issue is hard to explain since I am not 100% sure my self, what is going on. I will therefor try my best to explain the situation.

Just a warning, if you are hoping there will be code you have to look at and try to find an error, I am afraid I cannot provide such a thing, since it is more a general problem I am facing instead of an error in a code.

So... lets begin

I have a Excel AddIn, a WPF Application and a WCF Server all written by me and I can adjust any side, if that may be neccassary.

In my Excel AddIn, I call WCF Server methods to retrieve data from the WPF application.

Upon, opening a Excel Workbook my AddIn will update its values, and therefor call WCF Server.

This works fine, when the user "normally" opens the Excel Workbook, but fails when this happens "automatically" by code.

One such scenario is, that the mentioned Excel Workbook is linked in a MS Word Document multiple times, with a field function for example

{ LINK Excel.Sheet.12 "C:\test.xlsx" "Sheet1!R1C1" } 

When a user opens the MS Word Document, containing multipe of those links to the same file, MS Word will open the Excel Workbook for each link and after "evaluating" it, it then closes the workbook.

So, if the MS Word Document has 10 links to the same Excel Workbook, it will open/close this Excel Workbook 10 times.

This again, is no problem.

Now, comes the catch.

When the user has an Excel instance running, before opening the MS Word Document, it will fail opening the linked Excel Workbook at the second link with a message stating, the workbook is already open, if you open it a second time all changes will get lost do you wish to continue.

So for some reason, the first time the Workbook got opened, MS Word failed to close it.

Through, a lot of trial and error, I localized the error to be a call to my WCF Server.

The call is:

ReturnObject result = server.GetBatch(parameters, baseClass); 

When I call this line, it seems as if Excel doesnt block MS Word from continuing its works, so while MS Word already is trying to close and open the next link, I am still in the routine to get all information from my WCF Server, and since I still have a reference to the Excel Workbook at Hand, MS Word just simply cannot close the workbook.

The method is defined as this in my interface:

[OperationContract()] ReturnObject GetBatch(List<Parameter> parameters, ClientInfo clientInfo); 

As you can see, I dont use Task<ReturnObject>, so I expect it to run synchronous and block the running thread.

I have done a little testing around calling the method and could fix my problem with those two approaches:

1st approach:

ReturnObject result = null; Thread th = new Thread(() => { result = server.GetBatch(parameters, baseClass); }); th.Start(); while (th.IsAlive) {  } 

2nd approach:

ReturnObject result = null; BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (sender, args) => { result = server.GetBatch(parameters, baseClass); }; bw.RunWorkerCompleted += (sender, args) => {  }; bw.RunWorkerAsync();  while (bw.IsBusy) {  } 

Both approaches, do basically the same with the only difference the first creates a Thread and the second a BackgroundWorker.

The goal I had in mind, with those 2 is to "off-load" the call to WCF Server and block the calling thread with a simple while loop.

You may imagine, that I am not really happy with those "solutions".

Is there a way to let Excel block "entirely" when calling my WCF Server method?

What does actually happen here, as I dont really undertand what "magic" is happening, I only guess some "Synchronization.Context" switching is taking place, but I really have no clue?

1 Answers

Answers 1

The point is that the call to your server.GetBatch is already blocking, but the caller is just part of a parallel task activity.

The only difference with your workaround is that the while loop is eating cpu resources and that indirectly blocks the execution.

What you can really consider, is to look at managing concurrency at the WCF service level.

Just one reference among many:

When the service is configured with ConcurrencyMode.Single, WCF will provide automatic synchronization to the service context and disallow concurrent calls by associating the context containing the service instance with a synchronization lock. Every call coming into the service must first try to acquire the lock. If the lock is unowned, the caller will be allowed in. Once the operation returns, WCF will unlock the lock, thus allowing in another caller.

For a more extended reference to the correct WCF synchronization, here it is another link.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,                   ConcurrencyMode = ConcurrencyMode.Single)] public class BatchService : IBatchService { } 

enter image description here

Read More

Wednesday, October 11, 2017

WCF - Abort stream from client to server if server throws a FaultException

Leave a Comment

We have a WCF service that accepts a stream from a client (client uploading a file to server). However, if the server throws a FaultException before or during the stream the client just carries on streaming until the end regardless, at which point it receives the FaultException from the server - wasting time & bandwidth for the client.

Similar Question:

How to Abort a WCF File Upload from the Server-Side Method

Take the following (simplified WCF service)

Namespace JP_WCF     <ServiceContract> _     Public Interface IJP_WCF         <OperationContract> _         <FaultContract(GetType(JP_WCF_Fault))> _         Sub UploadFile(request As JP_WCF_FileUpload)          <OperationContract> _         <FaultContract(GetType(JP_WCF_Fault))> _         Function fakeError(ByVal int1 As Integer, ByVal int2 As Integer) As Integer          <OperationContract> _         <FaultContract(GetType(JP_WCF_Fault))> _         Function Ping() As Date     End Interface      <MessageContract> _     Public Class JP_WCF_FileUpload         Implements IDisposable          <MessageHeader(MustUnderstand:=True)> _         Public FileName As String          <MessageHeader(MustUnderstand:=True)> _         Public Length As Long          <MessageBodyMember(Order:=1)> _         Public FileByteStream As System.IO.Stream          Public Sub Dispose() Implements IDisposable.Dispose             If FileByteStream IsNot Nothing Then                 FileByteStream.Close()                 FileByteStream = Nothing             End If         End Sub     End Class      <DataContract> _     Public Class JP_WCF_Fault         <DataMember> _         Public Property EventID() As Integer         <DataMember> _         Public Property Message() As String         <DataMember> _         Public Property Description() As String          Public Sub New(ByVal _EventID As Integer, ByVal _Message As String, ByVal _Description As String)             Me.EventID = _EventID             Me.Message = _Message             Me.Description = _Description         End Sub     End Class  End Namespace 

Example Server method:

Try     Dim sourceStream As Stream = request.FileByteStream     Dim uploadFolder As String = "C:\upload\"     Dim filePath As String = Path.Combine(uploadFolder, request.FileName)      Using targetStream = New FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)         sourceStream.CopyTo(targetStream)         targetStream.Close()         sourceStream.Close()     End Using Catch ex As Exception     Throw New FaultException(Of JP_WCF_Fault)(New JP_WCF_Fault(8, ex.Message, ex.ToString), ex.Message) End Try 

Example Client Method:

Dim fileInfo As New System.IO.FileInfo(filePath) Dim startTime As DateTime = DateTime.Now Console.WriteLine("Starting V2 upload: " + DateTime.Now.ToString())  Dim JPCS As New JP_WCFService.JP_WCFClient()  Using stream As New System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)     Using uploadStreamWithProgress As New JP_StreamWithProgress(stream)         AddHandler uploadStreamWithProgress.ProgressChanged, AddressOf uploadStreamWithProgress_ProgressChanged         Try             JPCS.UploadFile(fileInfo.Name, fileInfo.Length, uploadStreamWithProgress)         Catch ex As FaultException(Of JP_WCFService.JP_WCF_Fault)             Console.WriteLine("Upload Error: " & ex.Detail.Message & " (EventID: " & ex.Detail.EventID.ToString & ")")         End Try     End Using End Using Dim endTime As DateTime = DateTime.Now Dim durationInMS As Double = (endTime - startTime).TotalMilliseconds Console.WriteLine(vbCr & "V2 Upload Completed: " + DateTime.Now.ToString() + " (" + durationInMS.ToString() + ")") JPCS.Close() 

web.config

<system.serviceModel>     <bindings>         <customBinding>             <binding name="JP_WCFBinding">                 <!-- maxReceivedMessageSize 600MB, maxBufferSize 2MB -->                 <binaryMessageEncoding compressionFormat="GZip" />                 <httpsTransport transferMode="Streamed" maxReceivedMessageSize="629145600" maxBufferSize="2097152"/>             </binding>         </customBinding>     </bindings>     <services>         <service behaviorConfiguration="JP_WCFbehavior" name="JP_WCF.JP_WCFServices">             <endpoint address="" binding="customBinding" bindingConfiguration="JP_WCFBinding" contract="JP_WCF.IJP_WCF"/>         </service>     </services>     <behaviors>         <serviceBehaviors>             <behavior name="JP_WCFbehavior">                 <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />                 <serviceDebug includeExceptionDetailInFaults="true" />             </behavior>         </serviceBehaviors>     </behaviors>     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> 

app.config

 <system.serviceModel>     <bindings>         <customBinding>             <binding name="CustomBinding_IJP_WCF">                 <binaryMessageEncoding compressionFormat="GZip" />                 <httpsTransport transferMode="Streamed" />             </binding>         </customBinding>     </bindings>     <client>         <endpoint address="https://dev-wcf.localhost/JP_WCF.svc"             binding="customBinding" bindingConfiguration="CustomBinding_IJP_WCF"             contract="JP_WCFService.IJP_WCF" name="CustomBinding_IJP_WCF" />     </client> </system.serviceModel> 

1 Answers

Answers 1

If you're concerned about the performance of this call, you could always make a server call to check the validity of this upload prior to streaming it. That way you can avoid streaming the file at all if there's a problem and avoid any exception state in your application (also expensive).

So you would make relatively quick trip to the server to validate things like

  1. valid file location
  2. permission to write to that location
  3. the size of the file being valid
  4. any relevant business rules

Then you can make your call without trying to manage application flow using exceptions. Remember: Exceptions should be for exceptional circumstances. This way if your application does raise an exception, it means that something very abnormal has happened and a dip in speed is more palatable (since this case would be theoretically very rare).

Read More

Saturday, October 7, 2017

AngularJs application unable to authenticate user login with Wcf Service

Leave a Comment

I am consuming Wcf Service into Angular Js Application . I have one Boolean function inside the wcf service to accept the username and password. I am trying to create user login system by using Angular Js Application but when I enter the correct username and password its does not working according my expectation. There are no errors showing in Google Chrome console windows.

Here is Interface .

  [OperationContract]         [WebInvoke(Method = "POST",         RequestFormat = WebMessageFormat.Json,         ResponseFormat = WebMessageFormat.Json,         //BodyStyle = WebMessageBodyStyle.WrappedRequest,         UriTemplate = "/AuthenticateUser")]         bool AuthenticateUser(UserLogin userLogin); 

Here is Implementation ..

 public bool AuthenticateUser(UserLogin userLogin)         {             // ConfigurationManager class is in System.Configuration namespace             string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;             // SqlConnection is in System.Data.SqlClient namespace             using (SqlConnection con = new SqlConnection(CS))             {                 SqlCommand cmd = new SqlCommand("spAuthenticateUser", con);                 cmd.CommandType = CommandType.StoredProcedure;                  //Formsauthentication is in system.web.security                 string encryptedpassword = FormsAuthentication.HashPasswordForStoringInConfigFile(userLogin.Password, "SHA1");                  //sqlparameter is in System.Data namespace                 SqlParameter paramUsername = new SqlParameter("@UserName", userLogin.Username);                 SqlParameter paramPassword = new SqlParameter("@Password", encryptedpassword);                  cmd.Parameters.Add(paramUsername);                 cmd.Parameters.Add(paramPassword);                  con.Open();                 SqlDataReader rdr = cmd.ExecuteReader();                 while (rdr.Read())                 {                     int RetryAttempts = Convert.ToInt32(rdr["RetryAttempts"]);                     if (Convert.ToBoolean(rdr["AccountLocked"]))                     {                         return false;                     }                     else if (RetryAttempts > 0)                     {                         int AttemptsLeft = (4 - RetryAttempts);                         //lblMessage.Text = "Invalid user name and/or password. " +                         //    AttemptsLeft.ToString() + "attempt(s) left";                     }                     else if (Convert.ToBoolean(rdr["Authenticated"]))                     {                         return true;                     }                  }                 return false;             }         } 

Here is Script code .

///// <reference path="../angular.min.js" />      var app = angular.module("WebClientModule", [])      .controller('Web_Client_Controller', ["$scope", 'myService', function ($scope, myService) {          $scope.OperType = 1;          //1 Mean New Entry            //To Clear all input controls.           function ClearModels() {             $scope.OperType = 1;             $scope.Username = "";             $scope.Password = "";           }           $scope.login = function () {             var User = {                 Username: $scope.Username,                 Password: $scope.Password,               };             if ($scope.OperType === 1) {                  var promisePost = myService.AuthenticateUser(User);                 promisePost.then(function (pl) {                     $scope.Id = pl.data.Id;                     window.location.href = "/Welcome/Index";                      ClearModels();                 }, function (err) {                     $scope.msg = "Password Incorrect !";                     console.log("Some error Occured" + err);                 });             }          };        }]);  app.service("myService", function ($http) {     // Create new record        this.AuthenticateUser = function (User) {         return $http.post("http://localhost:52098/HalifaxIISService.svc/AuthenticateUser", JSON.stringify(User));     } }) 

Here is the HTML code..

@{     Layout = null; }  <!DOCTYPE html>  <html> <head>     <meta name="viewport" content="width=device-width" />     <title>Index</title>     <script src="~/Scripts/angular.min.js"></script>     <script src="~/RegistrationScript/LoginScript.js"></script> </head> <body>     <table id="tblContainer" data-ng-controller="Web_Client_Controller">         <tr>             <td>              </td>         </tr>         <tr>             <td>                 <div style="color: red;">{{Message}}</div>                 <table style="border: solid 4px Red; padding: 2px;">                      <tr>                         <td></td>                         <td>                             <span>Username</span>                         </td>                         <td>                             <input type="text" id="username" data-ng-model="Username" required="" />                         </td>                     </tr>                     <tr>                         <td></td>                         <td>                             <span>Password</span>                         </td>                         <td>                             <input type="password" id="password" required data-ng-model="Password" require="" />                         </td>                     </tr>                      <tr>                         <td></td>                         <td></td>                         <td>                             <input type="button" id="login" value="Login" data-ng-click="login()" />                          </td>                     </tr>                 </table>             </td>         </tr>     </table> </body> </html> <script src="~/RegistrationScript/LoginScript.js"></script> 

Here is the screen shot when I run the application.Click here to see the result

Any Help or suggestion will he highly appreciated.

2 Answers

Answers 1

I ran your example in jsfiddle to see what's going on and I changed this:

<body ng-app="WebClientModule"> 

I added the ng-app attribute and now is working properly.

See the full example below:

https://jsfiddle.net/s99t344y/2/

Answers 2

You are not initialising the angular module in html side, you should add

data-ng-app="WebClientModule" 
Read More

Thursday, October 5, 2017

PHP SOAP Clients http headers Error

Leave a Comment

I need to consume a web service https://www.example.com/example.svc?wsdl in PHP. For this purpose, I am using PHP SOAP client. The code snippet like below:

$client = new SoapClient("https://www.example.com/example.svc?wsdl",     array('soap_version' => SOAP_1_2,         'location'=>'https://www.example.com/example.svc',         'login'=> '#####',         'password'=> '#######',         'exceptions'=>true,         'trace'=>1,         'cache_wsdl'=>WSDL_CACHE_NONE,         'encoding'=>'UTF-8',         'connection_timeout' => 500,         'keep_alive' =>false));  $client->__call('getProductList',array()); 

However, when I run this its through following error:

Warning: SoapClient::__doRequest(): SSL: The operation completed successfully. in E:\location\test1.php on line 37  Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in E:\location\test1:37 Stack trace: #0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'https://travius...', 'Travius/ITraviu...', 2, 0) #1 E:\location\test1(37): SoapClient->__call('getProductList', Array) #2 {main} thrown in E:\location\test1.php on line 37 

I am struggling several days to solve the error but can't figure out. I tried the different solution in stack overflow like 'keep_alive' =>false, connection_timeout but nothing works.

I also try with php nusoap library. its request and response are like following:

Error  HTTP Error: Unsupported HTTP response status 400 Bad Request (soapclient->response has contents of the response)  Request  POST /#####.svc?wsdl HTTP/1.0 Host: #####.#####.eu User-Agent: NuSOAP/0.9.5 (1.123) Content-Type: application/soap+xml;charset=UTF-8; charset=UTF-8 SOAPAction: "" Authorization: Basic RGVtb2FwaTpEdXE1dmRWdA== Content-Length: 529  <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><GetProduct><parameters><intProductID xsi:type="xsd:int">1266</intProductID><lang xsi:type="xsd:string">CN</lang></parameters></GetProduct></SOAP-ENV:Body></SOAP-ENV:Envelope>  Response  HTTP/1.1 400 Bad Request Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Mon, 02 Oct 2017 16:03:04 GMT Content-Length: 0 

Please note that this web service works fine in .Net application. Any help highly appreciated. Thanks in advance.

2 Answers

Answers 1

Judging from the error that you posted in your question please change the following line.

$client->__call('getProductList',array()); 

with this

try {     $soapResponse = $client->__soapCall('getProductList',array());     var_dump($soapResponse); }  catch (SoapFault $e) {      exit("Error using method \"getProductList\" having errorCode \"".$e->faultcode."\""); } 

I don't know what php version you use (you have not posted relevant information) but i think in your case _call is deprecated.

Calling this method directly is deprecated. Usually, SOAP functions can be called as methods of the SoapClient object; in situations where this is not possible or additional options are needed, use SoapClient::__soapCall().

Answers 2

Hi Did you try to write your soap header as wssecurity you can see samples

or this in stackoverflow

Read More

Wednesday, July 19, 2017

How to call a WCF service from javascript?

Leave a Comment

I'm trying to call a WCF service from an ajax call with jQuery. I manage to call the WCF from SOAP-UI and from Excel/VBA. My problem comes from the OPTIONS request that's sent and no POST follows:

  • if I set URL to http://mywcf/service.svc, OPTIONS is sent and I get a 400 Bad Request status and POST request is not sent. In this case, there's missing HTTP/1.1 in header (comparing with SOAP-UI headers).
  • if I set URL to http://mywcf/service.svc HTTP/1.1, OPTIONS is sent and I get a 200 OK status but POST request is not sent. In this case, HTTP/1.1 seems to be interpreted as a filename.

Can someone tell me how to call a POST action on a WCF from javascript and to add HTTP/1.1 header without corrupting service URL?

Here is a extract from my ajax call:

var soapData = ''         +'<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mic="http://microsoft.wcf.documentation">'         +'    <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://docs.oasis-open.org/ws-rx/wsrm/200702">'         +'        <wsrm:Sequence>'         +'            <wsrm:Identifier>s:Sender a:ActionNotSupported</wsrm:Identifier>'         +'            <wsrm:MessageNumber>1</wsrm:MessageNumber>'         +'        </wsrm:Sequence>'         +'        <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>'         +'        <wsa:ReplyTo>'         +'            <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>'         +'        </wsa:ReplyTo>'         +'        <wsa:MessageID>uuid:'+ MsgUid +'</wsa:MessageID>'         +'        <wsa:To>'+ Url +'</wsa:To>'         +'    </soap:Header>'         +'    <soap:Body xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">'         +'        <wsrm:CreateSequence>'         +'            <wsrm:AcksTo xmlns:wsa="http://www.w3.org/2005/08/addressing">'         +'                <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>'         +'            </wsrm:AcksTo>'         +'            <wsrm:Offer>'         +'                <wsrm:Identifier>urn:soapui:'+ SeqUid +'</wsrm:Identifier>'         +'            </wsrm:Offer>'         +'        </wsrm:CreateSequence>'         +'    </soap:Body>'         +'</soap:Envelope>';  $.ajax({     type: 'POST',     url: 'http://mywcf/service.svc', // with or without +' HTTP/1.1'     data: soapData,     contentType: 'application/soap+xml;charset=UTF-8',     dataType: 'xml' }); 

Values in my WCF web.config:

<system.webServer>     <httpProtocol>         <customHeaders>             <add name="Access-Control-Allow-Origin" value="*" />             <add name="Access-Control-Allow-Methods" value="POST, OPTIONS" />             <add name="Access-Control-Allow-Headers" value="*" />         </customHeaders>     </httpProtocol> </system.webServer> 

3 Answers

Answers 1

To consume a web service using jQuery, that is to make a call to the WCF service, you either use jQuery.ajax() or jQuery.getJSON(). In this article I used the jQuery.ajax()method.

To set the request, first define a variable. This will be helpful when you are calling multiple methods and creating a different js file to call the WCF service.

<script type="text/javascript">      var Type;     var Url;     var Data;     var ContentType;     var DataType;     var ProcessData; 

The following function initializes variables which are defined above to make a call to the service.

function WCFJSON() {     var userid = "1";     Type = "POST";     Url = "Service.svc/GetUser";     Data = '{"Id": "' + userid + '"}';     ContentType = "application/json; charset=utf-8";     DataType = "json"; varProcessData = true;      CallService(); } 

The CallService function sends requests to the service by setting data in $.ajax.

// Function to call WCF  Service        function CallService() {     $.ajax({         type: Type, //GET or POST or PUT or DELETE verb         url: Url, // Location of the service         data: Data, //Data sent to server         contentType: ContentType, // content type sent to server         dataType: DataType, //Expected data format from server         processdata: ProcessData, //True or False         success: function(msg) {//On Successfull service call             ServiceSucceeded(msg);         },         error: ServiceFailed// When Service call fails     }); }  function ServiceFailed(result) {     alert('Service call failed: ' + result.status + '' + result.statusText);     Type = null;     varUrl = null;     Data = null;      ContentType = null;     DataType = null;     ProcessData = null; } 

Note: The following code checks the result.GetUserResult statement, so your result object gets the property your service method name + Result. Otherwise, it will give an error like object not found in Javascript.

function ServiceSucceeded(result) {     if (DataType == "json") {         resultObject = result.GetUserResult;          for (i = 0; i < resultObject.length; i++) {             alert(resultObject[i]);         }      }  }  function ServiceFailed(xhr) {     alert(xhr.responseText);      if (xhr.responseText) {         var err = xhr.responseText;         if (err)             error(err);         else             error({ Message: "Unknown server error." })     }      return; }  $(document).ready(     function() {         WCFJSON();     } ); </script> 

Answers 2

Add webHttpBinding endpoint

    <services>   <service name="Contract">     <endpoint address="json" binding="webHttpBinding"  contract="IContract" bindingConfiguration="ActionsHttpBinding" behaviorConfiguration="ActionrestfulBehavior"/>   </service> 

then call the endpoint from ajax as post or get, see below example :

    var data = JSON.stringify({     param1: val1,     param2: val2 }); $.ajax({     url: "http://mywcf/service.svc/json/FunctionName",     type: "POST",     data: data,     contentType: "application/json; charset=utf-8",     dataType: "json",     processData: true }).then(function (rsutlt) {  }).fail(function (fail) { }); 

Answers 3

Add below code to your global.asax.cs, and remove customHeaders from your web config.

protected void Application_BeginRequest(object sender, EventArgs e)     {         HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");          if (HttpContext.Current.Request.HttpMethod == "OPTIONS")         {             //These headers are handling the "pre-flight" OPTIONS call sent by the browser             HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");             HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");             HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");             HttpContext.Current.Response.End();         }      } 

Also you need remove OPTIONSVerbHandler for enabling cors.

 <system.webServer>     <validation validateIntegratedModeConfiguration="false" />     <handlers>       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />       <remove name="OPTIONSVerbHandler" />       <remove name="TRACEVerbHandler" />       <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />     </handlers> </system.webServer> 
Read More

Wednesday, June 21, 2017

Xamarin Android - Making a Rest request with a complex parameter (object) throws exception, in .NET it works fine (Using channel factory)

Leave a Comment

I'm starting to use mono droid or Xamarin for Android, so, my idea was to reuse most of the code that I already use in .NET.

One of the things I need my android and ios application to do is to make calls to web services made available using wcf rest with json encoding.

So my code is simple:

WebHttpBinding webBinding = new WebHttpBinding(); EndpointAddress endPointAddress = new EndpointAddress("http://192.168.126.24:8025/Services/SecurityManagement"); ChannelFactory<ISecurityManagement> newFactory = new ChannelFactory<ISecurityManagement>(webBinding, endPointAddress);  newFactory.Endpoint.Behaviors.Add(new WebHttpBehavior() { DefaultOutgoingRequestFormat = System.ServiceModel.Web.WebMessageFormat.Json, DefaultOutgoingResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json });  newFactory.Endpoint.Behaviors.Add(new RestEndPointBehavior());  ISecurityManagement newProxy = newFactory.CreateChannel(); ValidateUserExistenceOutput output = newProxy.ValidateUserExistence(new ValidateUserExistenceInput() { Domain = "CRITICAL", Username = "myUserName" }); 

Simple enough to get me started (at least, that was my idea about mono, make in .net reuse in mono)

But when I run this code I get the following exception exception:

System.NotSupportedException: Loading... 07-25 10:43:40.922 E/mono    ( 1950):  07-25 10:43:40.922 E/mono    ( 1950): Unhandled Exception: 07-25 10:43:40.922 E/mono    ( 1950): System.NotSupportedException: Conversion from the argument parameterType 'BusinessOrchestration.SecurityManagement.InputObjects.ValidateUserExistenceInput' is not supported 07-25 10:43:40.922 E/mono    ( 1950):   at System.ServiceModel.Dispatcher.QueryStringConverter.ConvertValueToString (System.Object parameter, System.Type parameterType) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono-rt ( 1950):   at System.ServiceModel.Dispatcher.WebMessageFormatter+WebClientMessageFormatter.SerializeRequest (System.ServiceModel.Channels.MessageVersion messageVersion, System.Object[] parameters) [0x00000] in <filename unkno07-25 10:43:40.922 E/mono    ( 1950):   at System.ServiceModel.Dispatcher.WebMessageFormatter+WebClientMessageFormatter.SerializeRequest (System.ServiceModel.Channels.MessageVersion messageVersion, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono    ( 1950):   at System.ServiceModel.Description.WebHttpBehavior+ClientPairFormatter.SerializeRequest (System.ServiceModel.Channels.MessageVersion messageVersion, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono    ( 1950):   at System.ServiceModel.MonoInternal.ClientRuntimeChannel.CreateRequest (System.ServiceModel.Dispatcher.ClientOperation op, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono    ( 1950):   at System.ServiceModel.MonoIn 07-25 10:43:40.922 E/mono-rt ( 1950): [ERROR] FATAL UNHANDLED EXCEPTION: System.NotSupportedException: Conversion from the argument parameterType 'BusinessOrchestration.SecurityManagement.InputObjects.ValidateUserExistenceInput' is not supported 07-25 10:43:40.922 E/mono-rt ( 1950):   at System.ServiceModel.Dispatcher.QueryStringConverter.ConvertValueToString (System.Object parameter, System.Type parameterType) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono-rt ( 1950):   at System.ServiceModel.Dispatcher.WebMessageFormatter+WebClientMessageFormatter.SerializeRequest (System.ServiceModel.Channels.MessageVersion messageVersion, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono-rt ( 1950):   at System.ServiceModel.Description.WebHttpBehavior+ClientPairFormatter.SerializeRequest (System.ServiceModel.Channels.MessageVersion messageVersion, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono-rt ( 1950):   at System.ServiceModel.MonoInternal.ClientRuntimeChannel.CreateRequest (System.ServiceModel.Dispatcher.ClientOperation op, System.Object[] parameters) [0x00000] in <filename unknown>:0  07-25 10:43:40.922 E/mono-rt ( 1950):   at System.Servic The program 'Mono' has exited with code 0 (0x0). 

I'm using the exact same code in a .NET 4.5 application and it works fine, it seems that its failing when converting the object to a string (a json string, I suppose).

Should it work directly in mono since it works in .NET?

Do you guys have services with complex input objects? What api do you use to make these calls?

Thanks ahead for all your help,

Luis Pinho

1 Answers

Answers 1

It doesn't work because some of the object used in your code hasn't been ported to Mono since they are Microsoft specific. There is some information here : Mono Class Status

For example, this namespace Microsoft.EnterpriseManagement used for ISecurityManagement in your code will probably never be ported.

To work on both Mono or .Net your code must follow the .NET standard. It's a work in progress to harmonize Mono, .Net and .Net Core framework so they could compile common libraries and programs with less code differences.

Read More

Monday, June 12, 2017

How to display set access permission & display /hide div based on database values

Leave a Comment

I want to set access permissions page where setting the permissions to the user to only view selected divs only for example:

There are 5 checkboxes in admin page and 5 divs in user page if check 3 div user has to get 3 div only I am mapping userlocation & client location & username for setting access permissions and how to display / hide the div in user page based on the checkbox selection or database values?

There is a user login separately and admin login separately. The admin will disable certain features for certain users. Using wcf rest and sql server as backend.

1 Answers

Answers 1

Before we get into the answer I have to mention security. You probably know, but for future readers benefit...you must not rely on simply hiding or not generating HTML elements as a means of restricting user access. Why - because when your form submits data to the server this can be observed with simple tools like Fiddlr. If you simply hide important inputs on the web page but still submit them, then a mischievous user could use something like Postman to edit and submit dodgy values to your server INCLUDING for the fields that were not visible on the form. Even if you have some server-side code to restrict the generation of the HTML for the restricted inputs, if a user is able to see a full form submit, or more likely if your API is self-describing or well documented, then they can fire up Postman and start sending your server all manner of hooky data.

For this reason it is vital that you re-validate the user, their role and their right to modify at the server at each interaction. Sermon over.

Assuming the above protection is in place then the way forward is relatively simple. In your HTML you assign classes to the elements that need to show/hide and you send a variable from the server to dictate their hidden or visible state.

For example, say you have two groups of users called usrNormal and usrAdmin. You might have an input defined as:

<input type="text" class="usrNormal usrAdmin" name="somedata" style="display:hidden;"></input> <input type="text" class="usrAdmin" name="admindata" style="display:hidden;"></input> <div class="usrNormal usrAdmin" style="display:hidden;">Some important info here....</div>  <div class="usrAdmin" style="display:hidden;">Some admin-only info here....    </div> 

The key to this technique is the css class setting class="usrNormal usrAdmin"

And the accompanying JS function is:

var usrType = "usrNormal"; function protect() { $("." + usrType).show(); } protect();

I have used JQuery here in the line inside the function, you could use plain JS to achieve the same. We start the page with the important inputs, divs and other html elements hidden. The usrType setting comes from the server, and when the protect() function is called it finds all elements with the given user type class and makes them visible.

EDIT: See working snippet below. Though contrived the idea is clear I hope. One point to consider is the use of a generic marker class to indicate that the appropriate elements should take part in the show/hide operation. Let me know if you have any queries.

$( document ).ready(function() { // Important: wait for the document dom to be ready      // get the value of the server access variable - simulated by the radio buttons in this case    // var access = <you would put your server value here !>    var access = ".usrNormal";    setAccess(access);        // next part is just to let you play.    $('.serverVal').on('change', function(e){       setAccess($(this).val());       })      // key function - this will show pr hide based on classes.    function setAccess(accessVal) {        // next line finds all elements with class including 'usrAccess' and shows if they have the request class or otherwise hides.      $(".usrAccess").each( function() {        var ele = $(this); // readability          showHide(ele, accessVal);        })        }        // show or hide the element based on class    function showHide(ele, cls){          if ( ele.is(cls) ){ // pay attention - this uses the jquery 'is' feature.        ele.show();          }      else {       ele.hide();      }           }      });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <form name="form1">    <p>      <span>This selection simulates the value passed from the server. When changed the elements with the matching classes are shown or hidden.</span><br />    </p>    <p>      <span>        <input type="radio" class="serverVal" id="usrType1"  name="usrType" value=".usrNormal"  checked="1" />        <label for="usrType1"> Normal User only</label>      </span>      <span>        <input type="radio" class="serverVal" id="usrType2"  name="usrType" value=".usrAdmin"/>        <label for="usrType2"> Admin User only </label>      </span>      <span>        <input type="radio" class="serverVal" id="usrType3"  name="usrType" value=".usrAdmin, .usrNormal" name="usrType3"/>        <label for="usrType3"> Both </label><br />      </span>    </p>    <hr>    <p class="usrNormal usrAccess" style="display:none;">      <label for="somedata">Normal only</label>      <input type="text" name="somedata" />    </p>    <p class="usrAdmin usrAccess" style="display:none;">      <label for="admindata1">Admin only</label>      <input type="text" class="usrAdmin" name="admindata1"  />    </p>    <p class="usrNormal usrAccess" style="display:none;">      <label for="someinfo">Info 1</label>      <textarea id="someinfo">This textare is visible to normal users...</textarea>     </p>    <p class="usrAdmin usrAccess" style="display:none;">      <label for="admininfo">Info 2</label>      <textarea id="admininfo">This textare is visible to only Admin users...</textarea>     </p>      </form>

Read More

Thursday, June 1, 2017

WARN:Authentication error: ntlm authorization challenge expected, but not found in Soap UI

Leave a Comment

I am trying to access WCF Webservice using Windows Authentication in Soap UI.

I am getting 401 unauthorized.

Following are the set up I done.

  1. In Request Authorization Tab, I have given as NTLM

  2. I have given username, password and Domain.

As well as WSS-Password Type: PasswordText or PasswordDigest, and Wss-TimeToLive: 2000

Tried for Basic and Kerberos as well. Getting 401 response ONLY..

Getting following in the http log.

WARN:Authentication error: ntlm authorization challenge expected, but not found

What needs to be done to solve this issue?

1 Answers

Answers 1

I am assuming you are connecting to a VPN in order to access the webservice, and that you have already verified the credentials are correct (ie: by accessing the endpoint in a browser). I will also assume your soapUI's ntlm configuration is correct.

If so, add -Djava.net.preferIPv4Stack=true to your .vmoptions file (under bin directory).

Read More