Friday, November 20, 2009

Axis 2 WS-Security (rampart) FAQ

@YaronNaveh

Rampart is the WS-Security module of Axis2.
Prabath summarizes all the current posts that were published in the rampart FAQ blog.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Thursday, November 19, 2009

Generating meaningful names from a url

@YaronNaveh

A common programming task is to extract some meaningful name from a url.
One example is saving the contents of a url to a file name on disk - we need to have the name for the file.
Bellow there is a c# method that I have written that extracts this name + the results it produces on a few urls.


http://www.myServer.com/Services/Sanity.asmx?WSDL - Sanity
http://www.myServer.com/Services/Sanity.asmx?wsdl=1&xsd=2 - Sanity
http://www.myServer.com/Services/Sanity12345678901234567890123456789012345678901234567890123456789012.asmx - Sanity1234567890123456789012345678901234567
http://www.myServer.com/Services/Sanity.asmx - Sanity
http://www.myServer.com/Services/Sanity/ - Sanity
http://www.myServer.com/Services/Sanity - Sanity
http://www.myServer.com/Services/Sanity?wsdl - Sanity_wsdl
http://www.myServer.com/Services/Sanity/?wsdl - Sanity





public static string GetSuggestedNameFromUrl(string url, string defaultValue)
{
  const int MaxChars = 50;

  string res = Path.GetFileNameWithoutExtension(url);

  //check if there is no file name, i.e. just folder name + query string
  if (String.IsNullOrEmpty(res) || IsNameOnlyQueryString(res))
  {
    res = Path.GetDirectoryName(url);
    res = Path.GetFileName(res);

    if (String.IsNullOrEmpty(res))
       res = defaultValue;
  }

  res = ReplaceInvalidCharacters(res);

  if (res.Length > MaxChars)
     res = res.Substring(0, MaxChars);

  return res;
}


private static string ReplaceInvalidCharacters(string res)
{
  return Regex.Replace(res, @"[^\w]", "_", RegexOptions.Singleline);
}


private static bool IsNameOnlyQueryString(string res)
{
  return !String.IsNullOrEmpty(res) && res[0]=='?';
}

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Saturday, August 22, 2009

BindingBox: Convert WCF Bindings

@YaronNaveh



The WCF BindingBox is here!

What is it?
BindingBox is an online application that converts WCF bindings to a customBinding configuration.

Why we need it?
WCF bindings capture a general use case and allow us to customize it. For example, basicHttpBinding is good for interoperability with older soap stacks while WSHttpBinding fits WS-* based communication. However, there are cases where we can not use the out of the box bindings. For example:

  • We want to further customize the binding behind what it exposes. For example, we might want WSHttpBinding not to send a timestamp (for interoperability reasons) but this is not a built in option.

  • We have a special use case which is not captured by any of the out-of-the-box bindings. For example, we want to use binary encoding over http.

    In such cases we need to convert our binding into a custom binding. This is not a trivial process. In particular, some security settings can be very frustrating to translate.

    For this reason I have written the WCF BindingBox. This is an online application which automatically converts any binding to a customBinding.



    How to use it - Tutorial

    Step 1 - Get your current binding

    Just open your web.config or app.config file and navigate to the "<bindings>" element. Then copy its content to the clipboard. Be sure to copy the wrapping "<bindings>" element as well:


    <bindings>
       <wsHttpBinding>
         <binding name="MyBinding">
           <security>
            <message clientCredentialType="UserName" />
           </security>
         </binding>
        </wsHttpBinding>
    </bindings>


    Step 2 - Convert your binding

    Just navigate to the BindingBox and paste your binding from step 1. Then click on the "Convert to CustomBinding" button and copy to the clipboard your new binding. It may look like this:


    <customBinding>
       <binding name="NewBinding0">
         <transactionFlow />
         <security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
           <secureConversationBootstrap authenticationMode="UserNameForSslNegotiated" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
         </security>
         <textMessageEncoding />
         <httpTransport />
       </binding>
    </customBinding>


    Step 3 - Use the custom binding

    Basically, you now just need to use the BindingBox result as your binding configuration.

    In practice you would do it in one of the following ways:

  • In your .config file manually configure your endpoint to use a custom binding and set its configuration.
  • Use the WCF configuration editor to configure your endpoint to use a CustomBinding. then in your .config override the default customBinding configuraiton with the BindingBox result.


    Currently supported bindings

    BindingBox currently supports these bindings:

  • WSHttpBinding
  • WS2007HttpBinding
  • BasicHttpBinding


    More to follow

    Stay tuned for these:

  • NetTcpBinding
  • NetNamedPipeBinding
  • WSFederationHttpBinding
  • WS2007FederationHttpBinding


    Known issues

  • DefaultAlgorithmSuite is not converted
  • ReaderQuotas are not converted

    Please report any bug you find. Also feel free to submit an enhancement request.

    There is also a nice story behind BindingBox: It uses cutting edge technologies such as Windows Azure and MEF. More to come on this...

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!
  • Tuesday, July 28, 2009

    Debugging WCF

    @YaronNaveh

    j_saremi has posted a message in the WCF forum noticing that WCF source code can now be downloaded from Microsoft. The source can be viewed using the reflector since ever - no news here - but now it can actually be used to debug!

    Really, see:

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Cryptic WCF error messages (part 6 of N)

    @YaronNaveh

    If you have followed the previous parts of this series you already know it tries to diminish the mystery of WCF errors.

    When X.509 certificates are used you might get this error:


    The certificate 'CN=localhost' must have a private key that is capable of key exchange. The process must have access rights for the private key.


    The second part of the error implies that you may need to set permissions on the private key. I'll deal with that in a separate post.

    The first part of the error means that the certificate was created with a private key that is not capable of key exchange. This can happen when you use makecert.exe to create a test certificate without specifying the correct flags. The correct way to use makecert is:


    makecert -ss My -pe -n "CN=localhost" -sky exchange

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Saturday, July 25, 2009

    log4net gotcha: AppDomains

    @YaronNaveh

    We are using the log4net logging framework in a new project.
    In one initialization point of the application we init it:


    using log4net;
    using log4net.Config;

    XmlConfigurator.Configure(new FileInfo("log4net.config"));


    And in many other locations we use it:


    ILog log = LogManager.GetLogger(typeof(SomeClass));
    log.Debug("some debugging message");


    In one of my classes the messages I've logged did not appear in the log file (or in any of the other appenders). When I explicitly re-initialized log4net in the same class the messages were written successfully. A short investigation found the reason: This class is called from a different AppDomain than the other classes. log4net's LogManager class is static, which limits its scope to the calling AppDomain.

    Conclusion: log4net needs to be initialized once per AppDomain.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Why lawyers make more money than programmers

    @YaronNaveh

    Recently I have checked the possibility to bring Microsoft's Web Services Enhancements (WSE) 3.0 in the installation of a product I author. I already know that Microsoft products cannot be dispatched as is and I need a special redistributable version. Luckily, WSE3 has a Redistributable Runtime MSI.

    So I run this msi and the first stage in the installation wizard is the end user license agreement (EULA). Now I'm not a legalist but the beginning looks promising:


    These license terms are an agreement between Microsoft Corporation...and you. You may install and use one copy of the software on your device...


    "Microsoft...and you" sounds good, and "you may install" is what I wanted to hear anyway. But the second item is suspicious:


    SCOPE OF LICENSE
    ...
    You may not
  • work around any technical limitations in the software;

  • reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;

  • make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;

  • publish the software for others to copy;

  • rent, lease or lend the software;

  • transfer the software or this agreement to any third party; or

  • use the software for commercial software hosting services.


  • Now wait one second. If I may not transfer the software to any third party, then how can I redistribute this Redistributable Runtime MSI? Or is this EULA just an agreement between Microsoft and the third party, in which case where is the agreement between Microsoft and me? Am I not worth at least one or two vague terms?

    Anyway I passed this to our legal department. I better go work on some legacy code, which comparing to this looks more readable than ever...

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!