I want to authenticate app server against my central with license key and I do not want to include it as a parameter in my calls.
I have implemented custom ServiceAuthorizationManager but I am not sure what is the best way and place to set this licenseKey on client side.
I tried below (I might be completely wrong with approach)
<endpoint address="http://127.0.0.1:8000/ApiDataService" binding="wsHttpBinding"
contract="MyInterfaces.IApiDataService">
<headers>
<LicenseKey>MyLicenseKey</LicenseKey>
</headers>
</endpoint>
then in ServiceAuthorizationManager.CheckAccessCore(OperationContext operationContext)
I have managed to find a header's index via:
operationContext.RequestContext.RequestMessage.Headers.FindHeader("LicenseKey", "")
but retrieved HeaderInfo does not have my content any more.
I am sure it is in operationContext.RequestContext so I should be able to capture it somehow.
Any idead how?
Is there any nicer/standard way of doing this?
Should I use <identity\> element?
I am more than happy to use operationContext.ServiceSecurityContext but I do not know how to set it up on client side and where to place my custom license key.
I have multiple endpoints so I would prefer to have a single place for my license key. Setting it from code would be even better.
Thanks
This article here Globalization Patterns in WCF (WS-I18N implementation) may be of interest to you as it demonstrate how to use WCF out-of-band mechanisms to send and receive custom information. It's about globalization, not licensing of course, but the problem seems somewhat similar.
Related
New to Mulesoft and have a question regarding SOAP consumer for calling Web service.
Suppose there is a web service with a few operations. As an example the WS has operations for “createUser”, “validateUser”, “isAccountActive” and etc.
Let say “createUser” requires me to pass “userName”, “firstName”, “lastName”, “address”, “city”, “zipCode” and etc
While “validateUser” only requires “userName” only and “isAccountActive” requires “username” and “zipCode”
Suppose the information is coming as a http post in this format for createUser
<Service>
<operation>CreateUser</operation>
<userName>jdow123</userName>
<firstName>John</firstName>
<lastName>Dow</lastName>
<address>123 East street</address>
<city>NY</city>
<zipCode>123456</zipCode>
</Service>
And like this for isAccountActive
<Service>
<operation> isAccountActive </operation>
<userName>jdow123</userName>
<zipCode>123456</zipCode>
</Service>
So in this case does it make sense to create multiple subflows like the digram I have to handle each operation or there are better ways
Thanks
I would still use a sub-flow for each operation. One, it will allow reuse later and avoid duplicating code. It will allow you to test each operation individually and allow you to easily mock each sub-flow as part of a larger test - increasing testability.
As for the mapping to each sub-flow, you are currently using a choice router - It depends on you interface for that flow. If it’s a rest api you could use APIKit in Mule to map requests to a specific flow for create vs validate for example. But it all depends on your requirements.
If I have a web serice and a client consuming tis webservice, and then I change the service location, orI add another parameter, what is the usual way to change the client?
Do you necesarily need to update the client/ Was UDDI helping in this kind of situation?
You should definitely read Service Versioning - it has the information you need.
But the answer to your question is: maybe.
There are two types of changes: breaking and non-breaking. Unfortunately, sometimes it's not obvious what is a breaking or non-breaking change since it could depend on what the client is doing (and you may not have knowledge of how your service is being used).
In terms of changing the service location this is usually a breaking change. However, as you mention, if the client is using UDDI then they should be able to retrieve the new endpoint location and that change would not be a breaking change.
If you add another parameter then that might be a breaking change (or it might not). If the parameter is optional and the client is using lax versioning (e.g. WCF, .asmx) then the change should not be a breaking one. But it might be that the client is expecting a very specific format or they are doing some schema validation etc. and the optional parameter might cause a failure.
It depends on the nature of change you apply in the service definition. If you add something optional that only new clients can consume but the old clients can ommit, you have introduced a backward compatible change so the clients shouldn't be updated unless they decide to use this new feature. Any change that affects the way the existing clients use the service will require a client update as it represents a breaking change.
In the case of WCF, if you use the latest version 4.0, it introduces a new protocol implementation WS-Discovery, which can help clients to find the service url and the right version they can use. Using this approach, you can for instance, deploy a new version in a different url and the client applications can discover it automatically.
Regards
Pablo.
Hey without fully understanding your problem, and from what i can get from your questino it sounds like you need to update your web reference on the client.
If you have updated your references, not changed the location:
So Load up your client solution, then find your References (not dll references) but Web/Service References, and then right-click and select "update web references"
If you have changed the location, you can change the endpoint if you go to properties, but I would just delete the existing one and create a new one using the new location.
Hope it helps.
For more info check out http://msdn.microsoft.com/en-us/library/bb628652.aspx
I created a WCF project with one simple method that returns a pdf in a byte[] and a int (id #) and has username+password with a custom validator for message security and a SSL for transport security. Now the client tells me that he was assuming I was going to create a RESTful API instead. I don't have any experience with REST, but I've seen that you can create a REST project in WCF (which is what I'd prefer for interaction with the rest of my solution).
First, can you deliver a pdf the same way in a RESTful API? I set the int as an out parameter in order to return it to the client, can I assume an out parameter will function the same as well?
Second, can I use the same kind of security setup? I'm assuming the SSL will still protect the transport, but I cannot seem to find a good example or tutorial on basic security. I can use a different method of security if needed.
REST is different than SOAP or even WCF in that you aren't using cumbersome "envelopes" unfortunately those envelopes provide you with functionality like the authentication scheme you're using (and out params, etc.)
See Best Practices for securing a REST API / web service
You can go /w basic authentication + SSL for authentication. You must encrypt basic authentication though or else it is insecure. As for the out parameter, it seems that a composite XML based result like the following is one way to go:
GET
could return XML like:
<result>
<intValue>4</intValue>
<pdfByteString><![CDATA[bytestring...etc.]]></pdfByteString>
</result>
It actually does look like WCF does have some built-in functionality to help you out, this white paper should provide a decent intro:
http://msdn.microsoft.com/en-us/library/ee391967.aspx#Y1720
I have a universal service hosted on IIS7 that accepts a Message and returns Message ( with Action="*"). This service still publishes meta for the clients.
This metadata is explicitly specified using LocationUrl property in ServiceMetadataBehavior.
We have a requirement that the metadata can change during lifetime of the service, so in essence metadata has a lifetime.
I tried adding IWsdlExportExtension to the service endpoint behavior, but the ExportEndpoint method only gets called once (when the service is loaded first time). Is there a way for me to invalidate the loaded metadata so that anytime there is a call for wsdl using HttpGet, the behavior gets called ?
What you are asking for (changing the published service definition at runtime) is not possible - you need to remove the requirement which specifies that the metadata can change over time.
Once you've published a service, the only reason the service specification should change is because the service has been upgraded.
You should look closer at the business requirement which is making this technical requirement necessary, and try to find another way to satisfy it (perhaps post in programmers.stackexchange). Perhaps you can have multiple services available, and switch between the services over time - but this is a bit of a stab in the dark without knowing the business requirement.
No there is no way. Moreover if you needed you are up to your fully custom solution because this is out of scope of web services. Changing metadata means changing the service itself = its internal logic which always result in restarting the hosting process and publishing new metadata.
I'm writing what I'm referring to as a POJ (Plain Old JSON) WCF web service - one that takes and emits standard JSON with none of the crap that ASP.NET Ajax likes to add to it.
It seems that there are three steps to accomplish this:
Change "enableWebScript" to "webHttp" in the endpoint's tag
Decorate the method with [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
Add an incantation of [AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Allowed)] to the service contract
This is all working OK for me - I can pass in and am being returned nice plain JSON.
If I remove the WebInvoke attribute, then I get XML returned instead, so it is certainly doing what it is supposed to do. But it strikes me as odd that the option to specify JSON output appears here and not in the configuration file. Say I wanted to expose my method as an XML endpoint too - how would I do this? Currently the only way I can see would be to have a second method that does exactly the same thing but does not have WebMethodFormat.Json specified. Then rinse and repeat for every method in my service? Yuck.
Specifying that the output should be serialized to JSON in the attribute seems to be completely contrary to the philosophy of WCF, where the service is implemented is a transport and encoding agnostic manner, leaving the nasty details of how the data will be moved around to the configuration file.
Is there a better way of doing what I want to do? Or are we stuck with this awkward attribute? Or do I not understand WCF deeply enough?
I haven't fully tested this out yet, BUT, I took a look at WebMessageFormat in reflector and where it was used in code.
There is a attribute of the webHttp element called defaultOutgoingResponseFormat that can be set to "Json" or "Xml".
<behaviors>
<endpointBehaviors>
<behavior name="ServicesJSONEndpointBehavior">
<webHttp defaultOutgoingResponseFormat="Json"/>
</behavior>
</behaviors>
I've run into the same issue and typically crufted work-arounds after searching online without much info.
I'll give it a shot with multiple configured endpointBehaviors and report back.
UPDATE 6/5/2011
FYI -- I've ditched vanilla WCF with all its hair-pulling scenarios like this that should be simple, in favor of ServiceStack ( http://servicestack.net/ ). If you're looking to put together a standard REST style / document-oriented service over HTTP that out-of-the-box supports JSON / XML / CSV (and in the future protocol buffers) and that allows you to put together clean MVC-style routes with ease, give ServiceStack a hard look. There are a number of things that ServiceStack will handle rather easily and cleanly that always turn out to be a major PITA due to some wonky configuration issue or similar in standard WCF. ServiceStack uses it's own JSON serializer, which as an added bonus, outperforms DataContractJsonSerializer and JSON.NET as Demis mentions below.