Reference Books these days

Some amazing books which I am keeping with me these days for reference and going through portions whenever I get the opportunity.

Amazon List: http://amzn.com/w/LJTHFOO05T4U

TITLE

C# in Depth, Second Edition by Jon Skeet

CLR via C#, Second Edition (Pro Developer) by Jeffrey Richter (Author)

Framework Design Guidelines: Conventions, Idioms, and
Patterns for Reusable .NET Libraries (2nd Edition)
 
by Krzysztof Cwalina, Brad Abrams

Microsoft® .NET: Architecting Applications for the
Enterprise (Pro-Developer)​
 
by Dino Esposito, Andrea Saltarello

Microsoft® Application Architecture Guide, 2nd Edition
(Patterns & Pra​ctices)
 
by Microsoft Patterns & Practices Team (Author)

NHibernate 3.0 Cookbook by Jason Dentler

Patterns of Enterprise Application Architecture by Martin Fowler

Professional ASP.NET Design Patterns by Scott Millett

Programming Entity Framework: DbContext by Julia Lerman, Rowan Miller

 

Advertisements

Writing Fluent API in your applications

Fluent Interfaces / APIs are an amazing way of chaining methods and passing the input of the previous operation to the next operation. This reduces the amount of code required to declare similar objects or setting properties and configurations of the same object and makes the code more readable. Martin Fowler and Eric Evans coined the term back in 2005 (http://martinfowler.com/bliki/FluentInterface.html)

The implementation is very straight forward. The general pattern is to have chained methods each of which should be self-referential (should return object of its own type) and a terminating method to end the chain.

Following is a simplest example, a Number class which provides self-referential methods of operations returning the Number Object itself and an Equals method to terminate the chain.

    public class Number

    {

        private int _number;

        public Number(int num)

        {

            _number = num;

        }

        public Number Add(int num)

        {

            _number += num;

            return this;

        }

        public Number Subtract(int num)

        {

            _number -= num;

            return this;

        }

        public Number Multiply(int num)

        {

            _number *= num;

            return this;

        }

        public Number Divide(int num)

        {

            _number /= num;

            return this;

        }

        public int Equals()

        {

            return _number;

        }

    }

So, we can use the number class as follows by chaining the operations together.

              Console.WriteLine(

                new Number(10)

                .Add(10)

                .Subtract(5)

                .Multiply(10)

                .Divide(2)

                .Equals()

                );

Heart Surgery Pioneer Died

Michael E. DeBakey, 99, the father of modern cardiovascular surgery, who invented scores of medical procedures and instruments, developed the Mobile Army Surgical Hospital and established what later became the Veterans Affairs hospital system, died July 11 at Methodist Hospital in Houston. The hospital did not release the cause of death, but he had undergone heart surgery in 2006.

DeBakey stopped performing surgery at age 90, after more than 60,000 operations spanning a 70-year medical career.

http://www.washingtonpost.com/wp-dyn/content/article/2008/07/12/AR2008071201922.html

Passing Extra Information in WS-Security UserNameToken

(This post is a continuation of the previous post Using WSE 3.0 for Web Service Authentication)

Sometimes, apart from the user credential information passed in the WSE UserNameToken we might need to pass additional informaion in the UserNameToken. For example, in a recent scenario I had to implement multiple levels of authentication. The consumer of the service was required to pass a service level username and password which it can pass in the UserNameToken and also the service required additional Business User Authentication, so the consumer is required to pass this additional Business User credentials.

The Microsoft Implementation of WSE allows you to insert extra xml in the UserNameToken using the UserNameToken.AnyElements property of the Microsoft.Web.Services3.Security.Tokens.UsernameToken class. See the following code which is adding the ExtraUser XML in the UserNameToken.

Dim U As New Microsoft.Web.Services3.Security.Tokens.UsernameToken(“<User_Name>”, “<Password>”, Security.Tokens.PasswordOption.SendHashed)
Dim xmldoc As New System.Xml.XmlDocument()
Dim xmlElement As System.Xml.XmlElement = xmldoc.CreateElement(“ExtraUser”)
Dim xmlElement1 As System.Xml.XmlElement = xmldoc.CreateElement(“UserId”)
xmlElement1.InnerText = “testuser”
Dim xmlElement2 As System.Xml.XmlElement = xmldoc.CreateElement(“UserPass”)
xmlElement2.InnerText = “123”
xmlElement.AppendChild(xmlElement1)
xmlElement.AppendChild(xmlElement2)
U.AnyElements.Add(xmlElement)

This username token can then be passed in the WS-Security. The Service Provider needs to modify its CustomTokenManager class to authenticate the ExtraUser information. The following UserNameToken passed in the SOAP envelop shows how the additional informaiton is passed with the UserNameToken.

<wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”SecurityToken-2ee318dd-56ef-4f26-877d-2a199ff5b4e3″>
<wsse:Username>aleem</wsse:Username>
<wsse:Password Type=”
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest”>CyI4oSXQgRMdYF416fHcD0IDpIE=</wsse:Password>
<wsse:Nonce>NVU8Adj9tEMZQpBPoPfJMw==</wsse:Nonce>
<wsu:Created>2007-09-18T13:10:30Z</wsu:Created>
<ExtraUser><UserId>testuser</UserId><UserPass>123</UserPass></ExtraUser>
</wsse:UsernameToken>

Using WSE 3.0 for Web Service Authentication

Web Services Enhancements (WSE) is a webservice standard which provides cross-platform security for webservices. WSE provides various security specifications like WS-Security, WS-Policy, WS-Trust, WS-Privacy, WS-SecureConversation, WS-Federation, WS-Authorization which can be used to provide authentication, authorization and message level security using digital signing and encryption based on particular requirements on hand. More information on WSE and the areas it addresses can be seen here (This document is a old but provides a an overview of WSE security-model). Another good article on MSDN Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication explain different security scenarios and how WSE can be used in each one of them.

In the following I will provide a step-by-step detail on how to use WSE 3.0 for authenticating webservices with your custom user database. The custom database can be an ASP.NET Membership database or other custom user database. (You must have Visual Studio 2005 installed to proceed with the following. Please click on the images to enlarge)

1. Download WSE 3.0 from http://www.microsoft.com/downloads/details.aspx?FamilyID=018A09FD-3A74-43C5-8EC1-8D789091255D&displaylang=en and install it on your machine.

2. Create a new ASP.NET Webservice website project. Right Click the project select the “WSE Settings 3.0” option as shown below.

3. This will open the following WSE settings dialog. Select the “Enable this project for WSE” and “Enable Microsoft WSE Soap Protocol Factory” from the settings dialog.

4. Go to the Policy Tab and select “Enable Policy”. Add a new Policy with the name “CustomServicePolicy” (or any name).

5. After you add a new Policy, the following Policy settings wizard will open and you will be required to define your policy.

6. Select the Authentication method. The Authentication method can be Anonymous, Username, Certificate and Windows. In this sample I am going to select the username as we care going to pass username and password for the authentication. You can use other methods like windows if required. Also select that you are seting this policy for a service. (In case you are creating a policy for a client to access WSE webservice you can select the “Secure Client Application” option). Click next to proceed.

7. In the following screen you can select “Enable WS-Security 1.1 Extensions” and select Protection Order as “None”. You can select other protection methods if you want to sign and encrypt your messages using a X.25 certificate.

8. Click next to proceed, you will be shown the following screen with the informaiton about the Policy that you have defined.

9. After defining the Policy, go to you service class and add this Policy to the class using the Policy Attribute as shown in the following screenshot. You will be required to add Microsoft.Web.Services3.dll into your project to reference Policy attribute and other WSE classes. The WSE documentation says that this reference will be automatically added to your project if you enable WSE for your project as we did but I have observed that you have to manually add this reference and it is not added automcatically. You can get this dll from the following path C:\Program Files\Microsoft WSE\v3.0\ (The path may be different based on your installation location).

Note that after configuring WSE settings, there is an extra configuration file “wse3policyCache.config” which has been added to the project.

10. Now we need to write a Custom Token Manager which will authenticate the username and password sent by the user. Add a new Class “CustomTokenManager” in the project and inherit it from Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager. Override the AuthenticateToken method, WSE soap filter will call this method to obtain the clear text password for the user. You can write your custom code to access your ASP.NET membership database or other user database to obtain the password. You can get the username from the UsernameToken passed as a parameter to the AuthenticateToken method.

11. After you have you CustomTokenManager ready, you need to set this in web.config in the WSE security settings so WSE can use this class when user authentication is required.

 

Now your service is ready to use and it will authenticate the incoming user with your custom database usign the CustomTokenManager class that you have created.

To write a client for a WSE service, you need to have WSE 3.0 installed on the client machine. Moreover, you will have to enable WSE for your project (step 3) before adding the webreference to the server. If WSE is installed on the client machine and is enabled for your project, the WSDL.exe toll will generate an additional proxy class ending with Wse if the service supports WSE. In our case there will be two proxy classes that will be generated on the client. Service and ServiceWse. Use ServiceWse for accessing the service.

The following code shows how to pass username and password as UserNameToken in WS-Security header.

Dim oService As New WSETestService.ServiceWse

Dim U As New Microsoft.Web.Services3.Security.Tokens.UsernameToken(“<User_Name>”, “<Password>”, Security.Tokens.PasswordOption.SendHashed)
oService.SetClientCredential(U)

Dim oPolicy As New Policy()
oPolicy.Assertions.Add(New UsernameOverTransportAssertion())
oService.SetPolicy(oPolicy)

oService.HelloWorld()

Following is the SOAP request with the UserNameToken in the WSE header with username and password of the user. The password is passed as SHA-1 hash of the actual password. (Note that you selected Security.Tokens.PasswordOption.SendHashed inUserNameToken constructor from the client when creating the token, you can choose to send clear text password as well)

<inputMessage utc=”9/18/2007 1:10:30 PM” messageId=”urn:uuid:8c890d37-28a0-423f-8aaa-1b35e7f6a021″>
<processingStep description=”Unprocessed message”>
<soap:Envelope xmlns:soap=”
http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing” 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:Header>
<wsa:Action>
http://tempuri.org/HelloWorld</wsa:Action>
<wsa:MessageID>urn:uuid:8c890d37-28a0-423f-8aaa-1b35e7f6a021</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>
http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>
http://localhost:1841/WebServiceAuthentication/Service.asmx</wsa:To>
<wsse:Security soap:mustUnderstand=”1″>
<wsu:Timestamp wsu:Id=”Timestamp-dd031f35-cc14-4426-b34f-bfff66d03991″>
<wsu:Created>2007-09-18T13:10:30Z</wsu:Created>
<wsu:Expires>2007-09-18T13:15:30Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu=”
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”SecurityToken-2ee318dd-56ef-4f26-877d-2a199ff5b4e3″>
<wsse:Username>aleem</wsse:Username>
<wsse:Password Type=”
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest”>CyI4oSXQgRMdYF416fHcD0IDpIE=</wsse:Password>
<wsse:Nonce>NVU8Adj9tEMZQpBPoPfJMw==</wsse:Nonce>
<wsu:Created>2007-09-18T13:10:30Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>

</soap:Header>
<soap:Body>
<HelloWorld xmlns=”
http://tempuri.org/” />
</soap:Body>
</soap:Envelope>
</processingStep>
<processingStep description=”Entering SOAP filter Microsoft.Web.Services3.Design.RequireSoapHeaderAssertion+RequireSoapHeaderFilter” />
<processingStep description=”Exited SOAP filter Microsoft.Web.Services3.Design.RequireSoapHeaderAssertion+RequireSoapHeaderFilter” />
<processingStep description=”Entering SOAP filter Microsoft.Web.Services3.Design.UsernameOverTransportAssertion+ServiceInputFilter” />
<processingStep description=”Exited SOAP filter Microsoft.Web.Services3.Design.UsernameOverTransportAssertion+ServiceInputFilter” />
<processingStep description=”Processed message”>
<soap:Envelope xmlns:soap=”
http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing” 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:Header />
<soap:Body>
<HelloWorld xmlns=”
http://tempuri.org/” />
</soap:Body>
</soap:Envelope>
</processingStep>
</inputMessage>

Deleting Locked Workspace from Team Foundation Server

One thing I have noticed over the last year since I have started working with TFS is that it is highly sensitive to any changes/issues in the enviornment and easily gets currupted. However, TFS works wonderfully over the VPN connections far better than VSS. We initially struggled a lot on VSS while working remotely and it used to take a long time to check-in and would actually die if you were to take the latest of the whole project.

Anyway I got my solution corrupted due to some changes in the VPN settings in India Office, and was really stuck what to do about my already checked-out and locked files. I could restore the files one by one (they were only a few) but TFS got my old workspace locked and would’nt allow me to modify the files which are locked in the other workspace.

The solution is to unlock all files under a specific workspace and delete the old workspace. (This is only in case you are sure you can restore your changes manually). The Following TFS commands can be used

tf lock /lock:none /server:<server_name> /workspace:<my current workspace>;<domain>\<user> $/<project_name>

tf workspace /server:<server_name> /delete <my current workspace>;<domain>\<user>

If you do not know your workspace name or the previous user id you can list all tfs workspaces using the following.

tf workspaces /server:<server_name> /owner:*

Unfortunately, there are no options available in Visual Studio 2005 to do this, the workspace management option available in Visual Studio is extremely limited.