Monday, February 23, 2009

.NET client consuming Spring WS 1.5.5 using XWSS WS security Implementation

Introduction

I am currently working on an integration project where a .NET client has to consume a Java Web Service. Since I have been using Spring framework for a very long time, my natural inclination is to try out Spring WS 1.5.5 as the web service framework. So I picked spring framework 2.5.6, spring security 2.0.4 and spring web services 1.5.5 for the java web service implementation. I am using XWSS implementation of WS security under the hoods for the username token with password digest authentication mechanism.

The service consumer is a .NET client and apparently there were configuration issues with .NET that prevented them from consuming our service successfully. So I searched in google and posted the issue with Spring forums with no luck. So finally with the help of our .NET Software Engineer, I have managed to come up with a standard procedure as to how to consume a Java Web Service that implements WS security from a .NET client perspective.

Java Web Service Implementation

I am using Spring WS 1.5.5 Airline sample application that comes with its distribution to demonstrate the integration capability. The Airline sample is a normal web application that connects to an embedded HSQLDB database. This application uses XWSS implementation of WS-Security.

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">

<description>
This application context contains the WS-Security and Sprign Security beans.
</description>

<security:global-method-security secured-annotations="enabled"/>

<security:authentication-provider user-service-ref="securityService"/>

<bean id="securityService"
class="org.springframework.ws.samples.airline.security.SpringFrequentFlyerSecurityService">
<description>
A security service used to obtain Frequent Flyer information.
</description>
<constructor-arg ref="frequentFlyerDao"/>
</bean>

<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<description>
This interceptor validates incoming messages according to the policy defined in 'securityPolicy.xml'.
The policy defines that all incoming requests must have a UsernameToken with a password digest in it.
The actual authentication is performed by the Spring Security callback handler.
</description>
<property name="secureResponse" value="false"/>
<property name="policyConfiguration"
value="classpath:org/springframework/ws/samples/airline/security/securityPolicy.xml"/>
<property name="callbackHandler">
<bean class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
<property name="userDetailsService" ref="securityService"/>
</bean>
</property>
</bean>

</beans>
Spring ws currently supports two implementations of WS Security. One is based on XWSS and the other one is WSS4J from Apache.

XWSS


XWSS stands for XML and WebServices Security runtime. It is part of Project GlassFish and is used for securing WebServices requests and responses.

XWSS 2.0 was based on OASIS WSS specification version 1.0 and XWSS 3.0 is based on OASIS WSS specification 1.1

XwsSecurityInterceptor

The XwsSecurityInterceptor is an EndpointInterceptor that is based on SUN's XML and Web Services Security package (XWSS). This WS-Security implementation is part of the Java Web Services Developer Pack ( Java WSDP ). Like any other endpoint interceptor, it is defined in the endpoint mapping. This means that you can be selective about adding WS-Security support: some endpoint mappings require it, while others do not.

Note that XWSS requires both a SUN 1.5 JDK and the SUN SAAJ reference implementation. The WSS4J interceptor does not have these requirements.

The XwsSecurityInterceptor requires a security policy file to operate. This XML file tells the interceptor what security aspects to require from incoming SOAP messages, and what aspects to add to outgoing messages.

securityPolicy.xml

<xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken passwordDigestRequired="true" nonceRequired="true"/>
</xwss:SecurityConfiguration>

Spring WS endpoint Mappings
The endpoint mapping is responsible for mapping incoming messages to appropriate endpoints. There are some endpoint mappings you can use out of the box. Please refer the example in the applicationContext-ws.xml file below.

applicationContext-ws.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-1.5.xsd">

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean id="messageReceiver" class="org.springframework.ws.soap.server.SoapMessageDispatcher"/>

<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<description>
This bean wrap the messages.xsd (which imports types.xsd), and inlines them as a one.
</description>
<property name="xsds" value="/messages.xsd"/>
<property name="inline" value="true"/>
</bean>

<!-- ===================== ENDPOINTS ===================================== -->

<!--
The marshallingEndpoint and xpathEndpoint handle the same messages. So, you can only use one of them at the
same time. This is done for illustration purposes only, typically you would not create two endpoints which
handle the same messages.
-->

<bean id="marshallingEndpoint" class="org.springframework.ws.samples.airline.ws.MarshallingAirlineEndpoint">
<description>
This endpoint handles the Airline Web Service messages using JAXB2 marshalling.
</description>
<constructor-arg ref="airlineService"/>
</bean>

<!--
<bean id="xpathEndpoint" class="org.springframework.ws.samples.airline.ws.XPathAirlineEndpoint">
<description>
This endpoint handles the Airline Web Service messages using XPath expressions and JAXB2 marshalling.
</description>
<constructor-arg ref="airlineService"/>
<constructor-arg ref="marshaller"/>
</bean>
-->

<bean id="getFrequentFlyerMileageEndpoint"
class="org.springframework.ws.samples.airline.ws.GetFrequentFlyerMileageEndpoint">
<description>
This endpoint handles get frequent flyer mileage requests.
</description>
<constructor-arg ref="airlineService"/>
</bean>

<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>

<!-- ===================== ENDPOINT MAPPINGS ============================== -->

<!--
The endpoint mappings map from a request to an endpoint. Because we only want the security interception to
occur for the GetFrequentFlyerMileageEndpoint, we define two mappings: one with the securityInterceptor, and
a general one without it.
-->

<bean id="annotationMapping"
class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
<description>
Detects @PayloadRoot annotations on @Endpoint bean methods. The MarshallingAirlineEndpoint
has such annotations. It uses two interceptors: one that logs the message payload, and the other validates
it accoring to the 'airline.xsd' schema file.
</description>
<property name="interceptors">
<list>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="xsdSchemaCollection" ref="schemaCollection"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
</list>
</property>
<property name="order" value="1"/>
</bean>

<bean id="secureMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<description>
This endpoint mapping is used for endpoints that are secured via WS-Security. It uses a
securityInterceptor, defined in applicationContext-security.xml, to validate incoming messages.
</description>
<property name="mappings">
<props>
<prop key="{http://www.springframework.org/spring-ws/samples/airline/schemas/messages}GetFrequentFlyerMileageRequest">
getFrequentFlyerMileageEndpoint
</prop>
</props>
</property>
<property name="interceptors">
<list>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
<ref bean="wsSecurityInterceptor"/>
</list>
</property>
<property name="order" value="2"/>
</bean>


<!-- ===================== ENDPOINT ADAPTERS ============================== -->

<!--
Endpoint adapters adapt from the incoming message to a specific object or method signature. Because this
example application uses three different endpoint programming models, we have to define three adapters. This
is done for illustration purposes only, typically you would use one adapter, for instance the
MarshallingMethodEndpointAdapter.
-->


<sws:marshalling-endpoints/>

<sws:xpath-endpoints>
<sws:namespace prefix="messages"
uri="http://www.springframework.org/spring-ws/samples/airline/schemas/messages"/>
</sws:xpath-endpoints>

<bean class="org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter">
<description>
This adapter allows for endpoints which implement the PayloadEndpoint interface. The Get
FrequentFlyerMileageEndpoint implements this interface.
</description>
</bean>

<!-- ===================== ENDPOINT EXCEPTION RESOLVER ===================== -->

<!--
Endpoint exception resolvers can handle exceptions as they occur in the Web service. We have two sorts of
exceptions we want to handle: the business logic exceptions NoSeatAvailableException and NoSuchFlightException,
which both have a @SoapFault annotation, and other exceptions, which don't have the annotation. Therefore, we
have two exception resolvers here.
-->

<bean class="org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver">
<description>
This exception resolver maps exceptions with the @SoapFault annotation to SOAP Faults. The business logic
exceptions NoSeatAvailableException and NoSuchFlightException have these.
</description>
<property name="order" value="1"/>
</bean>

<bean class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver">
<description>
This exception resolver maps other exceptions to SOAP Faults. Both UnmarshallingException and
ValidationFailureException are mapped to a SOAP Fault with a "Client" fault code.
All other exceptions are mapped to a "Server" error code, the default.
</description>
<property name="defaultFault" value="SERVER"/>
<property name="exceptionMappings">
<props>
<prop key="org.springframework.oxm.UnmarshallingFailureException">CLIENT,Invalid request</prop>
<prop key="org.springframework.oxm.ValidationFailureException">CLIENT,Invalid request</prop>
</props>
</property>
<property name="order" value="2"/>
</bean>

</beans>



After deploying the above said service, the service will run at http://localhost:8080/airline/services. The wsdl is published at http://localhost:8080/airline/airline.wsdl

NOTE: There are other applicationContext xml files within the airline sample application which I am not mentioning here in this article for brevity. I would highly recommend you refer the sample airline application that comes with Spring WS 1.5.5 or 1.5.6.

There is already a .NET example within airline application which does not require to go to WS security intereceptor configured at the airline service level. The next section will give you enough details as to how to configure the .NET client side to access the airline sample service that goes through XWSS security interceptor configured within the application.

.NET client configuration using WSE 2.0

Prerequisites
:

1) Make sure you have WSE2.0 installed and .NET 1.1 (at least)

How do you verify the above prerequisite?


Check
whether Microsoft.Web.Services2.dll exists under C:\Program Files\Microsoft WSE\v2.0\Microsoft.Web.Services2.dll

If WSE 2.0 is not installed, please download it from here.

NOTE: The dll Microsoft.Web.Services2.dll plays the role of encrypting or decrypting the request and responses of the service.

.NET consuming Java Web Service

Please follow the steps below to consume web service using WSE 2.0

1. Enable WSE 2.0 extensions


In visual studio,
  • Select your project and right click
  • Select WSE setting 2.0 from the context menu
  • In the General tab, check 'Enable this project for Web Services Enhancements' checkbox
  • check 'Enable Microsoft Web Services Enhancement soap extensions'

2. Add Web References

In visual studio,
  • Select your project and right click
  • Select 'Add Web References' from the context menu
  • Enter the web service URL. For e.g. http://localhost:8080/airline/airline.wsdl
  • Hit go button to search the service
  • If the service is found, name the service and 'Add Reference'

3. How to verify whether the added service has WSE 2.0 service extension

  • Expand the service and open the source code of 'Reference.cs'
  • Class should extend Microsoft.Web.Services2.WebServicesClientProtocol

4. Changes in .NET Client class which consume the service

  • Include following namespace (this is to create 'UsernameToken')
using Microsoft.Web.Services2;
using Microsoft.Web.Services2.Security;
using Microsoft.Web.Services2.Security.Tokens;


  • In the code, add UsernameToken in the soap header

For e.g.,

UsernameToken un =
new UsernameToken("UN","Pwd", PasswordOption.SendHashed);
svc.RequestSoapContext.Security.Tokens.Add(un);

In the above example, replace UN with 'john' and PWD with 'changeme' since this is what airline sample application uses.

5. Changes in web.config

Add <configSections> element under the <configuration> element if it is not already added



<configSections>
<section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration,
Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>

Add <webServices> element under <system.web> element if not added



<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services2.WebServicesExtension, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
</soapExtensionTypes>
</webServices>


References

1. Spring WS 1.5.5 Reference Document
2. Spring WS forum
3. Microsoft .NET framework developer center (Article 1 and Article 2)

Conclusion

I hope this article will help any novice .NET software engineer in integrating with Java Web Services that implements WS Security. I sincerely thank my friend and colleague Mr. Thanasekaran Mariappan for helping me put together this article.

66 comments:

Arjen Poutsma said...

Nice job!

Artin said...

Any ideas about the other way around? I'm trying to get Spring WS to consume a .NET web service with WS-Security and am having no luck.

Vigil Bose said...

Aaron,

I have not tried it myself. However, what error are you getting?

Artin said...

Vigil -

Found out what the problem is. The .NET service I'm trying to consume implements WS-Security as well as WS-Addressing and WS-Trust. As far as I know, the WebServiceTemplate doesn't have any interceptors for WS-Trust, so I'm out of luck! I'm going to a Axis2 solution but have found that the documentation for consuming a web service is pretty bad everywhere.

Anonymous said...

make money online free [url]http://www.333eur.com/[/url]

Anonymous said...

link to [b]download software for windows[/b] are available here:

download software for windows
[url=http://www.downloadsoftwareforwindows]download software for windows[/url]

[url=http://www.downloadsoftwareforwindows/products/download-watermark-studio/productpage.php]download watermark studio[/url]

download dvd to iphone converter

Anonymous said...

url for [b]download software for windows[/b] is available here:

download software for windows
[url=http://www.downloadsoftwareforwindows.com]download software for windows[/url]

[url=http://www.downloadsoftwareforwindows.com/products/download-dvd-to-ipod-converter/productpage.php]download dvd to ipod converter[/url]

download youtube flv url

Anonymous said...

site to [b]software downloads[/b] is reachable at:

Windows YouTube downloader
[url=http://www.1800soft.com]Windows YouTube downloader[/url]

betting software
[url=http://www.betextremesoft.com]betting software[/url]

buy software for windows
[url=http://www.buysoftwareforwindows.com]buy software for windows[/url]

download software for windows
[url=http://www.downloadsoftwareforwindows.com]download software for windows[/url]

Download Youtube Videos
[url=http://www.downloadyoutubevideos.co.uk]Download Youtube Videos[/url]

FLV to AVI converter
[url=http://www.flvtoavi.co.uk]FLV to AVI[/url]

DVD ripper
[url=http://www.flvtodvd.com]DVD ripper[/url]

Video converter
[url=http://www.hollydollyvideo.com]Video converter[/url]

Home video converter software
[url=http://www.homevideopage.com]Home video software[/url]

Poker software
[url=http://www.pokerwinningvideo.com]Poker video software[/url]

Shark Video Downloader
[url=http://www.sharkvideopage.com]Shark Video Downloader software[/url]

Simplest YouTube Internet Video Downloader
[url=http://www.simplestutils.com]Watermark Software[/url]

Popular screensavers
[url=http://www.popularscreensaverpage.com]Popular Screensaver[/url]

Hyper YouTube Magic Tool XXX
[url=http://www.andromedaapps.com]Hyper YouTube Magic Tool XXX[/url]

Free FLV converter
[url=http://www.cassiopeiasoft.com]Free FLV converter[/url]

Working YouTube downloader
[url=http://www.pegasusapps.com]Working YouTube downloader[/url]

Anonymous said...

And I have faced it. Let's discuss this question.

Anonymous said...

Infatuation casinos? abolished over and beyond this untested [url=http://www.realcazinoz.com]casino[/url] president and form identify creditable online casino games like slots, blackjack, roulette, baccarat and more at www.realcazinoz.com .
you can also punt the scuttle our untrained [url=http://freecasinogames2010.webs.com]casino[/url] forsake at http://freecasinogames2010.webs.com and be remunerative in practical unfeeling dough !
another late-model [url=http://www.ttittancasino.com]casino spiele[/url] advance a extend is www.ttittancasino.com , thoroughly than of german gamblers, den of iniquity upon whilom unrestrained [url=http://www.realcazinoz.com]online casino[/url] bonus. so check this leading [url=http://www.omniget.co.il]online casino[/url] for free [url=http://www.casinosaction.com]casino bonus[/url] and 100's of online [url=http://www.thecasino.co.il]casino[/url] games.

Anonymous said...

I have to hear exactly what Tanner will do with that?!?


gabrielson insurance

Anonymous said...

Just popping in to say nice site.

Anonymous said...

Bonjour,
je suis nouveau ici j'aime vous lire ;)
je voulais vous remercier pour votre super site internet !
Bonne continuation
----
Nicolaseo, Rien de mieux que le referencement naturel.

sports handicapping software said...

a very interesting site has helped me all your information

Anonymous said...

top [url=http://norwegian-online-casinos.com/]casinos online[/url] coincide the latest [url=http://www.casinolasvegass.com/]free casino games[/url] unshackled no deposit hand-out at the leading [url=http://www.baywatchcasino.com/]baywatch casino
[/url].

Anonymous said...

Woаh! I'm really enjoying the template/theme of this site. It's
simplе, yеt effeсtive. A lot of times it's challenging to get that "perfect balance" between usability and visual appearance. I must say you've done a gгeat job with this.

Addіtionally, the blog loаds ѵery quick for me on Chrome.
Outstаndіng Blοg!

mу blog post; weight loss
Also see my site > weight loss

Anonymous said...

You nеed to bе a part of a cοntest for one of the highest quality siteѕ on thе nеt.
I am going to гecommenԁ thiѕ site!

my web blοg payday loans

Anonymous said...

Right for You, it is really less about him and more about
you. He says that he heard about it two months ago and Stassi and Jax
were together then. Iba ang pulitika at iba ang boxing (We
don't need mudslinging, just present your good intentions.

Feel free to surf to my web-site: The Tao of Badass

Anonymous said...

Goοd ωгite-up. I certainly appreciаte thіs sіtе.
Continue thе goοd woгk!

Feel free to visit my homepage; quick loans

Anonymous said...

Whаt's up mates, how is all, and what you want to say about this piece of writing, in my view its genuinely awesome in favor of me.

Feel free to surf to my web page payday loans no credit check

Anonymous said...

I wanteԁ tо thank you fоr this veгу gooԁ гead!

! I definitely loved evеry little bіt of it.
I've got you book marked to check out new things you post…

Stop by my web page payday loans

Anonymous said...

Ahаa, its fаstidіous converѕation regarding thіs рοst here at thіs
blog, I havе геad all thаt, so nоw me аlsо commеntіng at
this plaсе.

Alѕo νiѕit my weblog payday loans

Anonymous said...

Whаts up ѵery cοol blog!! Guy .. Bеautiful .
. Amazing .. I'll bookmark your blog and take the feeds additionally? I'm
satisfied to seek οut numeгous usеful info here within thе publish,
ωe want develop extra strаtegieѕ in thіѕ
regаrd, thanks for sharіng. . . . . .

My ωebѕitе ... payday loans online

Anonymous said...

Admiring the commitment you put into your website and in depth information you present.
It's good to come across a blog every once in a while that isn't
the same old rehashed material. Wonderful read!
I've saved your site and I'm adding your RSS feeds to my Google account.


My site; Air Jordan 2013central asia

Anonymous said...

Paragraph writing is also a excitement, if you be familiar with then you can write if not it is complex to write.


Feel free to surf to my blog post :: Air Max Pas Cherair jordan viii bugs bunny

Anonymous said...

I needed to thank you for this wonderful read!! I certainly enjoyed every little bit of it.
I have got you saved as a favorite to look at new stuff you post…

Also visit my web-site: Cheap Jerseys nfl articles

Anonymous said...

Wow, marvelous weblog format! How lengthy have you ever been running a
blog for? you make blogging glance easy. The whole look of your website is magnificent,
as smartly as the content material!

Also visit my web-site - Air Max 95jordan fly wade 2

Anonymous said...

You should take part in a contest for one of the best websites on the internet.
I am going to recommend this site!

Have a look at my homepage; Air Jordan Femmenike air jordan

Anonymous said...

Greate post. Keep writing such kind of info on your site.
Im really impressed by your blog.
Hey there, You've performed an excellent job. I'll certainly digg it and in my view suggest to my friends.

I'm sure they'll be benefited from this website.



Also visit my blog ... Cheap NFL Jerseyswholesale soccer je

Anonymous said...

If some one wishes expert view about blogging after that i advise him/her
to visit this blog, Keep up the good work.

Stop by my web site - Air Max Pas Cher

Anonymous said...

When I originally left a comment I seem to have clicked on the -Notify me when new comments
are added- checkbox and from now on every time a comment is added I receive 4 emails with
the exact same comment. Perhaps there is a means you
are able to remove me from that service? Kudos!


my web page ... Abercrombie Et Fitch

Anonymous said...

Hi! I know this is kind of off topic but I was wondering if you knew where I could locate a captcha plugin for my comment
form? I'm using the same blog platform as yours and I'm having difficulty
finding one? Thanks a lot!

Feel free to surf to my page Abercrombie Fitch Belgique

Anonymous said...

I feel this is one of the so much vital info for me.
And i'm satisfied studying your article. But want to statement on some common things, The site taste is ideal, the articles is actually great : D. Excellent task, cheers

Look at my blog post Air Jordan Pas Cher

Anonymous said...

Wow, that's what I was searching for, what a stuff! existing here at this website, thanks admin of this web page.

Take a look at my blog post ... www.officieelairmaxstore.nl

Anonymous said...

I am genuinely glad to glance at this webpage posts
which includes plenty of valuable information, thanks for providing such statistics.



Here is my web page; www.abercrombieandfitchbe.com

Anonymous said...

I am truly glad to read this website posts which carries tons of helpful data, thanks for
providing such data.

Also visit my web page - Air Max 93

Anonymous said...

Article writing is also a fun, if you be acquainted with then you can write otherwise it is complicated to write.



my site Louis Vuitton Handbags Outlet

Anonymous said...

Hurrah, that's what I was looking for, what a data! present here at this webpage, thanks admin of this website.

My blog post - Authentic Evgeni Malkin Jersey

Anonymous said...

Kеер this going please, great ϳоb!


Heгe is my site :: Payday Loans

Anonymous said...

I all the time emailed this web site post page to all my friends, for the reason that if like
to read it after that my links will too.

Feel free to visit my web site Cheap NFL Jerseys

Anonymous said...

Do you have a spam problem on this site; I also am a blogger, and I was wanting to know your
situation; many of us have created some nice methods and we
are looking to exchange methods with others, please shoot me an
email if interested.

Here is my website ... Cheap NFL Jerseys

Anonymous said...

Great beat ! I would like to apprentice while you amend your website,
how can i subscribe for a blog website? The account aided me a acceptable deal.

I had been tiny bit acquainted of this your broadcast provided bright clear concept

Feel free to visit my site: NFL Jerseys Cheap

Anonymous said...

Its like you read my mind! You appear to know so much about this, like you wrote the book in it or something.
I think that you can do with some pics to drive the message home a bit, but instead
of that, this is wonderful blog. A fantastic read.
I will certainly be back.

Look into my web-site :: source

Anonymous said...

Thanks for sharing your thoughts on chiefly. Regards

Also visit my web page :: Louis Vuitton Bags

Anonymous said...

Yesterday, while I was at work, my sister stole my iPad and tested to see if it can survive a twenty five foot drop, just so she
can be a youtube sensation. My apple ipad is now destroyed and she has 83 views.
I know this is entirely off topic but I had to share it with someone!


my web site; Louis Vuitton Handbags

Anonymous said...

Hello Thегe. I found уour blog the usage of msn.

Thіs is а veгy smartly written article. Ι will
be sure to booκmark it and retuгn to геаd eхtrа of yοuг uѕeful info.
Thanκ you for the post. Ӏ'll certainly return.

my web site Same Day Payday Loans

Anonymous said...

My brother recοmmended I might like thіs
website. Нe was entirely rіght.
This post truly maԁe my day. You cann't imagine just how much time I had spent for this information! Thanks!

Visit my website :: New Bingo Sites

Anonymous said...

I do not normally answer to posts but I'll in this case. WoW :)

Also visit my weblog; http://groupware.mg.inf.tu-dresden.de/node/40717

Anonymous said...

Ahaa, its fastidious dialogue concerning this article here at this website, I have read all that,
so at this time me also commenting here.

Here is my blog post :: Cheap NFL Jerseys

Anonymous said...

Nice answer back in return of this difficulty with real arguments and describing the whole
thing regarding that.

Here is my web blog - Nike Free Run Sko ()

Anonymous said...

It is appropriate time to make some plans for the future and it is
time to be happy. I've read this post and if I could I want to suggest you few interesting things or suggestions. Perhaps you could write next articles referring to this article. I wish to read even more things about it!

my web site Sac Louis Vuitton

Anonymous said...

I’m not that much of a online reader to be honest but your blogs really nice,
keep it up! I'll go ahead and bookmark your website to come back later on. Many thanks

Feel free to surf to my web page ... binaural beats recording

Anonymous said...

These are interesting ways you can use your books to rake in lots
of revenue for yourself. Today's small business owners are creating new turf on the internet. You can become a no cost lancer and create money online if you have certain abilities.

Also visit my homepage - make money online

Unknown said...

video security software

gives on-going to create during that time has been as of late conceded your security honour through Prime Reviews. This can be a first time that wills digital Security Computer programming has raised the top around three agenda that spots this instantly behind projects like.please click here
http://crazypixels.com

Unknown said...

nice blog for more details about this click here
video security software

Unknown said...

Our Experience:
Our company has more than 30 years of experience in Packing.
More than 23 years of research and application allows us to exclusively present the IPAC Gas Packing solution for long term preservation.

Our Team:
Comprised of mobile specialists, our team is trained in all of our services.
IPAC packaging processes and crating can all be done at your premises, at external yards or in our workshop. We even offer in-house contracts.

A unique Know-how:
IPAC has created the IPAC process which is a unique gas packaging solution.
This process ensures a physical chemical protection under modified atmosphere which is extremely safe.
http://www.ipac.ae/

Unknown said...

IPAC Specialized Packing LLC has been providing crating services, securement and industrial packaging services for over 30 years in Abu Dhabi, UAE.
We are committed to provide each customer with unsurpassed packaging products and wood crating services to exceed their expectations. We are dedicated to customer service, bringing an in-depth knowledge of all aspects of packing to every project.
Our staff is trained to professionally package your products and address any and all unexpected on-site job conditions.
http://www.ipac.ae/

Anishi Ganatra said...

Wonderful post here about XWSS WS security Implementation. I am sure it will be helpful for my team who are providing Hardware Engineering Service and working at Teq Diligent company. I would like to recommend this website and informative post with more people.

Unknown said...

Good.......... and very interesting stuffs thanks for sharing it.

Cloud Accounting Software

Bushraah88 said...

Thank you so much for letting me express my feeling about your post.
You write every blog post so well. Keep the hard work going and good luck.
Hope to see such beneficial post ahead to.
One Machine Learning
One data science

Bushraah88 said...

your article is valuable for me and for others. Thanks for sharing your information!www.bexteranutrition

카지노 사이트 said...

I really enjoy simply reading all of your weblogs. Thanks for sharing this information.
카지노 사이트
우리 카지노
바카라 사이트
온라인 카지노
라이브 카지노
던 카지노
첫번째 카지노
동전 카지노
예 카지노
더킹 카지노



Bushraah88 said...

Interesting stuff to read. Keep it up.nice information for a new blogger…it is really helpful and this is very informative and intersting for those who are interested in blogging field.
https://www.hindimei.net
movierulz
moviesrulz
HandandPaw.co
instagram-followers

Anonymous said...

Nice job!
gujranwala board 11th result 2019
Inter part 1 Result 2019
Multan board ics part 1 result 2019
lahore board inter part 1 result 2019
bise faislabad inter part 1 result 2019
sahiwal board result fsc part 1 2019

svrtechnologies said...

Really thanks for Posting such an useful and informative stuff...

mule training

Safi said...

Thank you for posting. I have the same as you think Marketing automation