Thursday, October 15, 2015

Asynchronous ICommand Implementation using TPL (System.Threading.Tasks.Task)

Asynchronous Implementation of ICommand I have implemented Asyn ICommand using Ssytem.Threading.Tasks.Task (i.e TPL). By using this implementation you can execute you command asynchronously. When new execution starts, new object of Task class creates every time and you business logic (which may take long time to complete) runs on that thread. So the main thread (i.e UI thread) gets free so it can be utilize to do other work.

Basically there are four actions which is going to be used to execute task asynchronously.


  • Execute Async Action:Async task which needs to be executed asynchronously.
  • CanExecute Action : which decides whether allow to execute async task or not.
  • OnComplete Action : what to call on successfully completion of aysnc task execution.
  • OnError Action : what to call when any error occurred during execution of async task.



        /// <summary>
        /// delegate which has the pointer of the main method which needs to be executed asynchronously.
        /// </summary>
        private readonly Action<T> _execute;

        /// <summary>
        /// delegate which has the pointer of the main method which needs to be executed asynchronously 
        /// it also provides facility to cancel the exection of async task
        /// </summary>
        private readonly Action<T, CancellationToken> _executeWithCancel;

        /// <summary>
        /// delegate which has the pointer of the method whose output decides whether to allow aysnc method to execute or not
        /// It disables the control to which it is binded (ex. button)
        /// </summary>
        private readonly Func<T, bool> _canExecute;

        /// <summary>
        /// delegate which has the pointer of the method which gets execute when async operation completes.
        /// </summary>
        private readonly Action _onComplete;

        /// <summary>
        /// delegate which has the pointer of the method which gets execute when any error occured during execution of async operation.
        /// the boolean flag value indicates that whether the async operation is cancelled manually or not.
        /// </summary>
        private readonly Action<Exception, bool> _onError;
 


About Task Parallel Library(TPL):

According to the post of TPL written by sacha barber on C# corner : ,
With the help of System.Threading.Tasks.Task we can create new thread and can execute our code asynchronously. The benefit of to use TPL is handles ThreadPool internally. Tasks will be allocated threads by the use of a ThreadPool, which handles the creation of Threads to carry out Tasks, so a lot of the heavy lifting (so to speak) is done behind the scenes for us by TPL.

The other great thing about TPL is that it is aimed at using each core of your CPU, which may have been otherwise idle. It obviously does this using Thread(s) behind the scenes, but you really do not have to get involved with spinning up new Threads at all (OK, in advanced scenarios such as custom Schedulers, maybe, but hey, more on that later; day to day, you really don't have to care about it).


Complete implementation of Aysnc ICommand class:

Copy the following code and paste in your program to use it.


    /// <summary>
    /// using constructor
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class AsyncActionCommand<T> : ICommand
    {
        #region Global Fields
        
        /// <summary>
        /// delegate which has the pointer of the main method which needs to be executed asynchronously.
        /// </summary>
        private readonly Action<T> _execute;

        /// <summary>
        /// delegate which has the pointer of the main method which needs to be executed asynchronously 
        /// it also provides facility to cancel the exection of async task
        /// </summary>
        private readonly Action<T, CancellationToken> _executeWithCancel;

        /// <summary>
        /// delegate which has the pointer of the method whose output decides whether to allow aysnc method to execute or not
        /// It disables the control to which it is binded (ex. button)
        /// </summary>
        private readonly Func<T, bool> _canExecute;

        /// <summary>
        /// delegate which has the pointer of the method which gets execute when async operation completes.
        /// </summary>
        private readonly Action _onComplete;

        /// <summary>
        /// delegate which has the pointer of the method which gets execute when any error occured during execution of async operation.
        /// the boolean flag value indicates that whether the async operation is cancelled manually or not.
        /// </summary>
        private readonly Action<Exception, bool> _onError;

        /// <summary>
        /// An instance of the <see cref="Task"/> class which contains the ref of the async operation thread.
        /// </summary>
        private Task _currentExecutingTask;

        /// <summary>
        /// Its a cancellation token to cancel the async operation when required.
        /// </summary>
        private CancellationTokenSource _taskCancellationTokenSource;

        #endregion

        #region Constructors
        
        /// <summary>
        /// Initialize the new instance of then AsyncDelegateCommand class
        /// </summary>
        /// <param name="executeMethod"> async Execute method delegate ref</param>
        /// <param name="canExecuteMethod"> canExecute method delegate ref</param>
        /// <param name="onComplete"> completion method delegate ref</param>
        /// <param name="onError"> error method delegate ref</param>
        public AsyncActionCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod = null,
                                     Action onComplete = null, Action<Exception, bool> onError = null)
        {
            _execute = executeMethod;
            _canExecute = canExecuteMethod;
            _onComplete = onComplete;
            _onError = onError;
        }

        /// <summary>
        /// Initialize the new instance of then AsyncDelegateCommand class
        /// </summary>
        /// <param name="executeMethod"> async Execute method delegate ref with cancellation token</param>
        /// <param name="canExecuteMethod"> canExecute method delegate ref</param>
        /// <param name="onComplete"> completion method delegate ref</param>
        /// <param name="onError"> error method delegate ref</param>
        public AsyncActionCommand(Action<T, CancellationToken> executeMethod, Func<T, bool> canExecuteMethod = null,
                                    Action onComplete = null, Action<Exception, bool> onError = null)
        {
            _executeWithCancel = executeMethod;
            _canExecute = canExecuteMethod;
            _onComplete = onComplete;
            _onError = onError;
        }

        #endregion

        #region Properties & Events
        
        /// <summary>
        /// Gets boolean value which indicates whether async task is being executing or not.
        /// </summary>
        public bool IsBusy
        {
            get
            {
                if (_currentExecutingTask == null)
                    return false;

                var isbusy = _currentExecutingTask.IsCompleted || _currentExecutingTask.IsCanceled || _currentExecutingTask.IsFaulted;
                return !isbusy;
            }
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        #endregion

        #region Public methods
        
        /// <summary>
        /// Executes long running aysn task.
        /// </summary>
        /// <param name="parameter">async task parameter</param>
        public void Execute(object parameter)
        {
            if (_execute != null)
            {
                _currentExecutingTask = Task.Factory.StartNew(() =>
                {
                    _execute((T)parameter);
                }).ContinueWith(task =>
                {
                    TaskCallback(_onComplete, _onError, task);
                }, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith(task => task.Dispose());
            }
            else
            {
                _taskCancellationTokenSource = new CancellationTokenSource();
                var token = _taskCancellationTokenSource.Token;

                _currentExecutingTask = Task.Factory.StartNew(new Action<object>((argument) =>
                {
                    _executeWithCancel((T)argument, token);
                }), parameter, token).ContinueWith(task =>
                {
                    TaskCallback(_onComplete, _onError, task);
                }, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith(task => task.Dispose());
            }
        }

        /// <summary>
        /// Decides whethe allow to execute async operation or not.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>Retruns true or false</returns>
        public bool CanExecute(object obj)
        {
            var status = true;

            if (_currentExecutingTask != null)
                status = _currentExecutingTask.IsCompleted || _currentExecutingTask.IsCanceled || _currentExecutingTask.IsFaulted;

            if (_canExecute != null && status)
                status = _canExecute((T)obj);

            return status;
        }

        /// <summary>
        /// Cancels the running async task 
        /// </summary>
        public void Cancel()
        {
            if (IsBusy && _taskCancellationTokenSource != null)
                _taskCancellationTokenSource.Cancel();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Its get execute when aysnc tasks get completed or any error occurred or cancelled manually
        /// </summary>
        /// <param name="onComplete">contains ref of competition method</param>
        /// <param name="onError">contains ref of error method</param>
        /// <param name="task">Async task ref</param>
        static void TaskCallback(Action onComplete, Action<Exception, bool> onError, Task task)
        {
            switch (task.Status)
            {
                case TaskStatus.Canceled: // executes when task is cancelled manually
                    if (onError != null)
                    {
                        var ex = new AggregateException(new Exception("Task has been canceled"));
                        onError(ex, true);
                    }
                    break;
                case TaskStatus.Faulted: // executes when erro occured during execution
                    if (onError != null) onError(task.Exception, false);
                    break;
                case TaskStatus.RanToCompletion: // executes when async task completed.
                    if (onComplete != null) onComplete();
                    break;
                default:
                    break;
            }
        }

        #endregion
    }


How to use the class : Example


public class MyClass
    {
        public ICommand AsyncCommand
        {
            get
            {
                return new AsyncDelegateCommand<object>(AsyncMethod, CanExecuteAsyncCommand, RunOnCompletion, RunOnError);
            }
        }

        private void AsyncMethod(object obj, CancellationToken token)
        {
            //Write logic here which is going be executed asynchronosuly
        }

        private void RunOnError(Exception arg1, bool arg2)
        {
           //Write logic here to catch the error if thrown from the async method execution.
        }

        private void RunOnCompletion()
        {
           //Write your logic to which want to execute after successfully completion execution of async method
        }

        private bool CanExecuteAsyncCommand(object obj)
        {
            return true; // write your code here to decide whether to execute aysn method or not.
        }
    }

Improvement is appreciated always

Thank You


Monday, November 7, 2011

How to render client report definition files (.rdlc) directly to the Response stream without preview



Note: I cover this technique in a more recent post here : Rendering an RDLC directly to the Response stream in ASP.NET MVC

A ReportViewer control is normally used to open a report definition file, process it and load it into the viewing area.
The simple method below allows you to render the report directly to the response stream without using the ReportViewer control. This might be useful in cases where you want to render a non interactive report.
The example below renders the report in PDF format. The other report types available when using the LocalReport.Render method are “Excel”and “Image”.


///
/// References:
///

private void RenderReport() {
LocalReport localReport = new LocalReport();
localReport.ReportPath = Server.MapPath("~/Report.rdlc");

//A method that returns a collection for our report
//Note: A report can have multiple data sources
List employeeCollection = GetData();

//Give the collection a name (EmployeeCollection) so that we can reference it in our report designer
ReportDataSource reportDataSource = new ReportDataSource("EmployeeCollection", employeeCollection);
localReport.DataSources.Add(reportDataSource);

string reportType = "PDF";
string mimeType;
string encoding;
string fileNameExtension;

//The DeviceInfo settings should be changed based on the reportType
//http://msdn2.microsoft.com/en-us/library/ms155397.aspx
string deviceInfo =
"" +
" PDF" +
" 8.5in" +
" 11in" +
" 0.5in" +
" 1in" +
" 1in" +
" 0.5in" +
"
";

Warning[] warnings;
string[] streams;
byte[] renderedBytes;

//Render the report
renderedBytes = localReport.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);

//Clear the response stream and write the bytes to the outputstream
//Set content-disposition to "attachment" so that user is prompted to take an action
//on the file (open or save)
Response.Clear();
Response.ContentType = mimeType;
Response.AddHeader("content-disposition", "attachment; filename=foo." + fileNameExtension);
Response.BinaryWrite(renderedBytes);
Response.End();

}

Note that if you change the ReportType in the Render method, you will also have to change the DeviceInfo settings.

Thursday, November 3, 2011

How to: Create and Install Temporary Certificates in WCF for Message Security During Development

 Summary of Steps
 Step 1: Create a Certificate to Act as Your Root Certificate Authority
 Step 2: Create a Certificate Revocation List File from the Root Certificate
 Step 3: Install Your Root CA on the Server and Client Machines
 Step 4: Install the Certificate Revocation List File on the Server and Client Machines
 Step 5: Create and Install Your Temporary Service Certificate
 Step 6: Give the WCF Process Identity Access to the Temporary Certificate’s Private Key
 Deployment Considerations
 Additional Resources
Objectives
 Learn how to create a root certificate for the temporary certificate used for WCF message security.
 Learn how to create a root certificate revocation list (CRL) file for the root certificate used to validate revocation.
 Learn how to create a temporary certificate for WCF message security.
 Learn how to install the temporary certificate.
 Learn how to install the root certificate for the temporary certificate.
 Learn how to install the root CRL for the root certificate.

Overview

When developing a WCF service that uses X.509 certificates to provide message security, it is necessary to work with temporary certificates. This is because production certificates are expensive and may not be readily available. There are two options for specifying trust on a certificate:

 Peer trust validates the certificate directly.
 Chain trust validates the certificate against the issuer of a certificate known as a root authority.

This how-to article discusses the chain trust option because it is the most commonly used approach in Business-to-Business (B2B) scenarios, and it is the default validation for WCF when using message security.

Additionally, a certificate revocation list (CRL) validation is performed during message security. This validation checks the list of certificates that were revoked by the root certificate. There are three modes of revocation:

 Online. The CRL list is retrieved and the check happens online, requiring connectivity to the URLs.
 Offline. The CRL list is retrieved, the check happens online and is then cached for subsequent validation.
 NoCheck. No validation is performed.

This how-to article discusses the CRL check without configuration changes when using message security.

To use chain trust validation during development time, you create a self-signed root certificate authority (CA) and install it in the Trusted Root Certification Authority location in the local machine.

The certificate used by WCF is signed by the root self-signed certificate and installed in the Personal store of the local machine. To ensure that the CRL check succeeds, you create a self-signed root CRL file and install it in the Trusted Root Certification Authority store of the local machine.

You will use makecert.exe to create a private key file and a certificate to act as your root CA. You will then create a CRL file from the private key that will act as your revocation list file for the root CA. Next, you will install the root certificate and CRL file. Finally, you will create and install the temporary certificate from the root certificate, using the private key to sign and generate the key.

Summary of Steps
 Step 1: Create a Certificate to Act as Your Root Certificate Authority
 Step 2: Create a Certificate Revocation List File from the Root Certificate
 Step 3: Install Your Root Certificate Authority on the Server and Client Machines
 Step 4: Install the Certificate Revocation List File on the Server and Client Machines
 Step 5: Create and Install Your Temporary Service Certificate
 Step 6: Give the WCF Process Identity Access to the Temporary Certificate’s Private Key

Step 1: Create a Certificate to Act as Your Root Certificate Authority

In this step, you use the makecert tool to create a root CA that will be used to sign your certificate. This certificate will be self signed and will only have the public key that will be used to do the trust chain validation when encrypting and signing messages. The self-signed certificate will act as a root certificate itself, instead of pointing to a Root authority in a chain of trust.

1. Open a Visual Studio command prompt and browse to the location where you want to save the certificate files.
2. Run the following command to create the root CA: other Copy

makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer

In this command:
 -n specifies the subject name for the root CA. The convention is to prefix the subject name with "CN = " for "Common Name".
 -r specifies that the certificate will be self-signed. This means that certificates created with this switch will act as a root certificate.
 -sv specifies the file that will contain the private key of the certificate. The file is always created, if it does not exist. This will allow creating certificates using the private key file for signing and key generation.
 RootCATest.cer specifies the name of the file containing the public key of the certificate. The RootCATes.cer file will not have the private key. This is the certificate that will be installed in the store for trust chain validation on the client and server machines.
3. In the Create Private Key Password dialog box, enter a password, confirm the password, and then click OK. Optionally, you can click None without entering the password, but this is not recommended for security reasons.
4. In the Enter Private Key Password dialog box, enter the password again and then click OK.
This is the password needed to access the private key file RootCATest.pvk in order to generate the file RootCATest.cer containing the public key.
This step creates a certificate named RootCATest.cer and a private key file named RootCATest.pvk.

Step 2: Create a Certificate Revocation List File from the Root Certificate


In this step, you create a CRL file that will be imported into the correct certificate stores of the client and service machines. You will create a CRL for the temporary root certificate. The CRL is necessary because WCF clients check for the CRL when validating certificates.

1. Open a Visual Studio command prompt and browse to the location where you want to save the CRL file for the root certificate.
2. Run the following command to create the CRL file: other Copy

makecert -crl -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.crl

In this command:
 -crl specifies that you want to generate the CRL file for the root certificate.
 -n specifies the subject name for the CRL. The convention is to prefix the subject name with "CN = " for "Common Name". You can give it the same name as the root CA.
 -r specifies that the CRL file will be self-signed. This means that CRL files created with this switch will act as revocation list files for the root CA.
 -sv specifies the file that will contain the private key for CRL file generation. There is no need to create this file because it already exists. This will allow creation of CRL files using the private key file for signing.
 RootCaTest.crl is the CRL file created with the command.

Step 3: Install Your Root CA Certificate on the Server and Client Machines

In this step, you install the certificate in the Trusted Root Certification Authorities location on both the server and client machines. All certificates that are signed with this certificate will be trusted by the client machine. Note: Important: Be sure to delete this certificate from the store after you have finished developing and testing for your application.

Repeat the following steps on both client and the server machines:

1. Copy the RootCATest.cer file to the client and server machines.
2. Click Start and then click Run.
3. In the command line, type MMC and then click OK.
4. In the Microsoft Management Console, on the File menu, click Add/Remove Snap-in.
5. In the Add Remove Snap-in dialog box, click Add.
6. In the Add Standalone Snap-in dialog box, select Certificates and then click Add.
7. In the Certificates snap-in dialog box, select the Computer account radio button because the certificate needs to be made available to all users, and then click Next.
8. In the Select Computer dialog box, leave the default Local computer: (the computer this console is running on) selected and then click Finish.
9. In the Add Standalone Snap-in dialog box, click Close.
10. In the Add/Remove Snap-in dialog box, click OK.
11. In the left pane, expand the Certificates (Local Computer) node, and then expand the Trusted Root Certification Authorities folder.
12. Under Trusted Root Certification Authorities, right-click the Certificates subfolder, select All Tasks, and then click Import.
13. On the Certificate Import Wizard welcome screen, click Next.
14. On the File to Import screen, click Browse.
15. Browse to the location of the signed Root Certificate Authority RootCATest.cer file copied in Step 1, select the file, and then click Open.
16. On the File to Import screen, click Next.
17. On the Certificate Store screen, accept the default choice and then click Next.
18. On the Completing the Certificate Import Wizard screen, click Finish.

The signed root CA certificate is now installed in the Trusted Root Certification Authorities store. You can expand the Certificates subfolder under Trusted Root Certification Authorities to see the RootCATest certificate installed properly.

Step 4: Install the Certificate Revocation List File on the Server and Client Machines

In this step, you install the CRL from the file in the Trusted Root Certification Authorities location on both the server and client machines. The CRL is checked during the certificate validation process. Note: Important: Be sure to delete the certificate from the store after you have finished developing and testing for your application.

Repeat the following steps on both the client and server machines:
1. Copy the RootCATest.crl file to the client and server machines.
2. Click Start and then click Run.
3. In the command line, type MMC and then click OK.
4. In the Microsoft Management Console, on the File menu, click Add/Remove Snap-in.
5. In the Add Remove Snap-in dialog box, click Add.
6. In the Add Standalone Snap-in dialog box, select Certificates and then click Add.
7. In the Certificates snap-in dialog box, select the Computer account radio button because the certificate needs to be made available to all users, and then click Next.
8. In the Select Computer dialog box, leave the default Local computer: (the computer this console is running on) selected and then click Finish.
9. In the Add Standalone Snap-in dialog box, click Close.
10. In the Add/Remove Snap-in dialog box, click OK.
11. In the left pane, expand the Certificates (Local Computer) node, and then expand the Trusted Root Certification Authorities folder.
12. Under Trusted Root Certification Authorities, right-click the Certificates subfolder, select All Tasks, and then click Import.
13. On the Certificate Import Wizard welcome screen, click Next.
14. On the File to Import screen, click Browse.
15. In Files of Type, select Certificate Revocation List.
16. Browse to the location of the signed Root Certificate Authority RootCATest.crl file copied in Step 1, select the file, and then click Open.
17. On the File to Import screen, click Next.
18. On the Certificate Store screen, accept the default choice and then click Next.
19. On the Completing the Certificate Import Wizard screen, click Finish.
The CRL for the root CA certificate is now installed in the Trusted Root Certification Authorities store. To view the CRL, click the Trusted Root Certification Authorities folder then press F5. A subfolder named Certificate Revocation List will be displayed. Expand this folder and you will see the RootCATest CRL installed properly.
Step 5: Create and Install Your Temporary Service Certificate
In this step, you create and install the temporary certificate on the server machine from the signed root CA created in the previous step.
1. Open a Visual Studio command prompt and browse to the location where you have the root CA certificate and private key file.
2. Run following command for creating a certificate signed by the root CA certificate: other Copy
makecert -sk MyKeyName -iv RootCATest.pvk -n "CN=tempCert" -ic RootCATest.cer -sr localmachine -ss my -sky exchange -pe
In this command:
 -sk specifies the key container name for the certificate. This needs to be unique for each certificate you create.
 -iv specifies the private key file from which the temporary certificate will be created. You need to specify the root certificate private key file name that was created in the previous step and make sure that it is available in the current directory. This will be used for signing the certificate and for key generation.
 -n specifies the key subject name for the temporary certificate. The convention is to prefix the subject name with "CN = " for "Common Name".
 -ic specifies the file containing the root CA certificate file generated in the previous step.
 -sr specifies the store location where the certificate will be installed. The default location is Currentuser, but since the certificate needs to be available to all users, you should use the localmachine option.
 -ss specifies the store name for the certificate. My is the personal store location of the certificate.
 -sky specifies the key type, which could be either signature or exchange. Using exchange makes the certificate capable of signing and encrypting the message.
 -pe specifies that the private key is generated in the certificate and installed with it in the certificate store. When you double-click the certificate, on the General tab, you should see a message at the bottom stating, “You have a
private key that corresponds to this certificate”. This is a requirement for message security. If the certificate does not have the corresponding private key, it cannot be used for message security.
3. In the Enter Private Key Password dialog box, enter the password for the root CA private key file specified in Step 2, and then click OK.
Step 6: Give the WCF Process Identity Access to the Temporary Certificate’s Private Key
In this step, you give the process identity of the WCF service access permissions to the certificate’s private key. If your service is hosted in Internet Information Services (IIS), the identity typically is "NT AUTHORITY\NETWORK SERVICE"; in a production scenario, or if your service is hosted in a Windows service, it could be a custom domain service account.
1. Open a Visual Studio command prompt.
2. Run the following command: other Copy
FindPrivateKey.exe My LocalMachine -n "CN=tempCert"
In this command:
 My is the store name where you have installed your temporary certificate.
 LocalMachine is the store location for your certificate.
 –n "CN=tempCert" is the common name for your temporary certificate. Note:
If FindPrivateKey is not on your machine, download the WCF samples, including the FindPrivateKey tool, at http://www.microsoft.com/downloads/details.aspx?FamilyId=2611A6FF-FD2D-4F5B-A672-C002F1C09CCD&displaylang=en.
FindPrivateKey returns the location of the private key for the certificate, similar to "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\4d657b73466481beba7b0e1b5781db81_c225a308-d2ad-4e58-91a8-6e87f354b030".
3. Run the following command to assign access permissions to the process identity of the WCF service. Note: You should give read-only permissions to the private key. 4. other 5. Copy
6.
7. cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\4d657b73466481beba7b0e1b5781db81_c225a308-d2ad-4e58-91a8-6e87f354b030" /E /G "NT AUTHORITY\NETWORK SERVICE":R
8.
9. In this command:
 /E edits the access control list (ACL) of the private key instead or replacing it. You should never replace the ACL but should only add the necessary permission to the process identity.
 /G grants the permission to the process identity.
 :R gives read-only permissions to "NT AUTHORITY\NETWORK SERVICE".
10. Run the following command to verify the permissions on the private key. This will display all the identities and the permissions that have access to the private key: other Copy
cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\4d657b73466481beba7b0e1b5781db81_c225a308-d2ad-4e58-91a8-6e87f354b030"
You should see the following in the output from this command: other Copy
NT AUTHORITY\NETWORK SERVICE:R
Note: If you are running Microsoft Windows® XP, give the certificate permissions for the ASPNET identity instead of the NT Authority\Network Service identity, because the IIS process runs under the ASPNET account in Windows XP.
Deployment Considerations
Temporary certificates should only be used for development and testing purposes. For real-world production environments, use a certificate provided by a CA such as Microsoft Windows Server® 2003 Certificate Services or a third party.

WCF service with username password authentication

http://codebetter.com/petervanooijen/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-things-they-don-t-tell-you/
The WCF framework is gigantic. It has such an enormous amount of possibilities that it’s pretty easy to get completely lost. For our scenario we needed just a small basic subset. Our application provides a set of services which are consumed by a diversity of clients which have to tell who they are by providing a custom username and password. There are loads and loads of documents and manuals to be found on the web but I didn’t find anything which gave me the complete story. Most of them follow all kinds of sidesteps in other parts of the rich WCF framework. Things we didn’t need at all, the things we needed to get our stuff to work were either omitted or only mentioned briefly in a comment.
This post tries to describe the full story. It will try to keep quiet on all noise on other cool, but unneeded, features. This information is assembled from a rich variety of stuff on the web and error messages provided by the WCF framework itself. The latter are often quite to the point and provide a lot of essential information. This post is just a kind of cookbook recipe, I don’t claim to understand every detail and would appreciate any comment to further clarify the details.

The service
The service is an ASP.NET service, hosted by IIS and configured in the system.ServiceModel part of the web.config.










The endpoint address is the root of the IIS site in which it his hosted. To use username authentication you need to use wsHttpBinding. The services functionality is described in the ICustomerDeskOperations contract.

In the binding you specify the credential type as username.








In the servicebehaviour you set up how the username is going to be validated










The username is custom validated. This is done by the FarmService.Authentication.DistributorValidator class in the FarmService assembly. This class inherits from WCF class UserNamePasswordValidator and overrides the Validate method.

public class DistributorValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
throw new SecurityTokenException("Username and password required");
var repository = new DistributorRepository();
if (! repository.IsKnownDistributor(userName, password))
throw new FaultException(string.Format("Wrong username ({0}) or password ", userName));
}
}

The method validates the incoming username and password in a repository and throws appropriate exceptions when needed. This is really custom code. As long as you don’t throw an exception the service invocation will be accepted.

So far this could have been a copy of many a story on the web. Except for one detail which is absolutely essential. For username password authentication to work your server hosting the service needs an X509 certificate. Else all service invocations will fail. This certificate is specified in the service behavior.



First you need a certificate. Instead of buying one (which is bound to a specific server address and thereby as good as useless for testing purposes) you can create your own. The .net framework comes with tools to generate these and there are several tutorials how to use these tools. Far more easier is selfcert a pluralsight tool which takes care of the whole process in a couple of clicks.

What they don’t tell you here is that you have to run the tool as administrator, else it will crash most ungracefully. What the tool is also unclear about is where to store the generated certificate. By default it is stored in MyStore. When validating the certificate it’s trustworthiness depends on the location it is stored. When the store is not trusted a chain of validation is started. Instead of setting up a chain of certificates you can also directly store your certificate in a trusted store.

With these settings the certificate is stored in a trusted location. The name and location match the settings in the service behavior.

Troubles don’t end here. After a while, like logging in the next time, the service host will start complaining it cannot find the private key of the certificate with a “Keyset does not exist” error message. What happens it that the service no longer has the access right to read the certificate. What helped me was explicitly setting rights on the certificate’s private key file.

Here I am using a blunt axe by just allowing everybody read rights on the certificate’s private key file. I’m no security expert but I am aware this is absolutely not the way to do things. But hey, I only want to build a service, never asked for this certificate stuff and the only thing I want to do here is get that out of the way in the development process.

Now the service is ready to be consumed by a client

The client

To consume this service add a service reference in the client. The mexHttpBinding in the service configuration enables to read all metadata form the service without any credentials.

Setting up a connection to the client requires some fiddling. Again not all of these settings are clear by default.

var endPoint = new EndpointAddress(new Uri(Farm.FarmUrl), EndpointIdentity.CreateDnsIdentity("Farm"));
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var result = new CustomerDeskOperationsClient(binding, endPoint);
result.ClientCredentials.UserName.UserName = Farm.FarmUserName;
result.ClientCredentials.UserName.Password = Farm.FarmPassword;

First we need an endpoint. This is assembled from the url in the client’s configuration, here a constant Farm.FarmUrl. For the custom username authentication to work the endpoint also needs an EndpointIndentity. According to the sparse msdn documentation this is to prevent phishing. The fact that the identity was needed and the parameter had to be the certificate’s name was suggested by the WCF error messages.

The security is set according to the security settings we have seen in the service. Both the username and password are set in UserName property of the ClientCredentails.

Wrapping up
This is it. Now our service and clients are talking. But it took far to much effort to find the right settings. The number is not great, but they all were found to be essential. Finding the right was a process of endlessly weeding out all sidesteps. I hope this well help you to get it done a little faster.


The many useful comments and their possibilities are summarized in this sequel. All misty things in this post are clarified there. Be sure to read it.

Certificate based Authentication and WCF

Certificate based authentication with WCF has two components - configuring credentials and determining trust.

The first part is easy - you simply set the clientCredentialType in the binding's security configuration to Certificate. This means that WCF will demand that the client sends a certificate along with the (first) request - either as a WS-Security X509 token or using SSL client certificates (depending on the security mode this also means that this requirement becomes part of the WSDL/Policy).

Furthermore the "plumbing" (either SSL or WCF message security) will make sure that the incoming certs are technically valid. This includes making sure that the certificate is not malformed and that the signature matches the public key. If this is not the case, the request gets rejected at a very low level and usually your service code would never get invoked.

At this point you have a technically valid certificate - but this does not necessarily mean that you also trust that certificate. The default validation strategy for certificates (regardless of message vs. transport) is called Chain Trust, this means:
• the certificate must be issued from a CA in your trusted CA list (in the machine certificate store)
• this intended purpose of that CA must include "Client Authentication"
• the current date/time must be within the certificate's validitiy period
With message security you also get a mode called Peer Trust. In this mode WCF simply checks if the incoming certificate is installed in the Trusted People folder in the certificate store (the expiration time is checked too).
When to use which mode?

Peer Trust

Since the Trusted People folder must hold all allowed certificates, this means that the service (or the client) has to know every peer a priori. This is OK if you have a limited amount of certificates that you want to allow - but does not scale very well. If you have more than one service on a machine and want to use peer trust, you have to run them under different accounts and use the current user certificate store to separate the "allowed" list.

Chain Trust

Chain trust is for scenarios where you don't know every certificate explicitly, but want to establish trust based on the issuer. The problem you have here is, that by default the trusted CA list is quite, errm, extensive. It includes popular CAs like VeriSign and not so popular ones (which I never heard before). So using chain trust it is quite easy to get a certificate that would be trusted by your service.
So in a lot of cases peer trust is not enough and chain trust is too much. What you typically want to have is first validating the trust chain and afterwards restrict to a specific CA or specific properties in the client cert. How do you accomplish that? Well - it depends ;)

In classic SSL transport security this is accomplished by using a Certificate Trust List (CTL). The moral equivalent in message based security is a X509 Certificate Validator. A third approach (which works in both modes) would be a WCF Service Authorization Manager.
In the next posts I will have a look at these technique and show you the up/down sides of each. Stay tuned.

Certificate based Authentication and WCF (Message Security)
When using message security, the intended way to validate an incoming credential (== token) is a token validator. You can find several internal validators in the System.IdentityModel.Selectors namespace (e.g. for UserName, X.509 or Windows tokens). The X509 token validators gets called whenever an incoming certificate has to be validated - when you have secure conversation enabled, this happens only on the first request which makes this approach very efficient.

WCF has three builtin validators for X.509 certificates and you can choose which one to use via a service/endpoint behavior. I will show the service side settings here, but the same switches also exist on the client side.






revocationMode="Online" />






The certificateValidationMode specifies how incoming certificates are validated and how trust is determined:

None. No validation is performed. Not recommended.
ChainTrust. The certificate has to chain up to one of the CAs in your trusted CA certificate folder.
PeerTrust. The incoming certificate has to be in the Trusted People certificate folder.
PeerOrChainTrust. A combination of Chain and Peer trust.
Custom. For all other cases.

The trustedStoreLocation attribute determines whether the current user or local machine store is used for peer or chain checks - defaults to local machine. Furthermore you specify how revocation lists should get checked via the revocationMode attribute (no check, offline or online).

See this post for a more detailed description of the validation modes. Also, as mentioned in that post, the standard validation modes are mostly useful in niche situations.

This is where the Custom mode comes into play. With this mode it is your responsibility to validate the certificate following your own guidelines. You then make decisions if you want to accept the certificate.

A custom certificate validator involves deriving from X509CertificateValidator and implementing the Validate() method. The WCF plumbing passes the incoming certificate into this method. If you want to reject the certificate you throw a SecurityTokenValidationException inside Validate().

So far so good - now, which steps are involved to validate a certificate? Before you can rely on any information in the cert, you have to make sure it's valid - typcially by checking it is not expired or revoked and is issued by a trusted CA.

Afterwards you can check certain properties of the certificate or its issuer to further restrict the allowed certs. Another approach would be - like PeerTrust - to check the certificate against a list of allowed certificates.

For checking the trust chain, you use the X509Chain class - the general logic of Validate() looks like this:

public override void Validate(X509Certificate2 certificate)
{
// create chain and set validation options
X509Chain chain = new X509Chain();
SetValidationSettings(chain);

// check if cert is valid and chains up to a trusted CA
if (!chain.Build(certificate))
{
throw new SecurityTokenValidationException(
"Client certificate is not valid");
}

// check if cert is from our trusted list
if (!IsTrusted(chain, GetTrustedThumbprints()))
{
throw new SecurityTokenValidationException(
"Client certificate is not trusted");
}
}
How the certificate should be exactly validated can be specified on the ChainPolicy property of X509Chain. Besides the configurable revocation mode, WCF uses the default settings for the chain policy, which are:

protected override void SetValidationSettings(X509Chain chain)
{
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
}

My implementation of IsTrusted then checks if either an issuer or a the end certificate itself (specified by the ValidationMode property) is in a trust list. The check is done by comparing the thumbprint of the certificate in question against a list.

protected virtual bool IsTrusted(X509Chain chain, string[] trustedThumbprints)
{
int depth = 0;

if (ValidationMode == ValidationMode.EndCertificate)
{
// only check the end certificate
return CheckThumbprint(chain.ChainElements[0].Certificate, trustedThumbprints);
}
else
{
// check the rest of the chain
foreach (X509ChainElement element in chain.ChainElements)
{
if (++depth == 1)
{
continue;
}

if (CheckThumbprint(element.Certificate, trustedThumbprints))
{
return true;
}
}
}

return false;
}


The last step is to register the validator in a serviceCredentials behavior.


x509FindType="FindBySubjectName"
storeLocation="CurrentUser"
storeName="My" />


customCertificateValidatorType="type" />



In the download you can find a ready to use validator base class from which you can derive from. You just have to implement the GetTrustedThumbprints method and return a string[] of thumbprints. You can get the thumbprints from the certificate UI (just remove the blanks). Have fun!

Steps to authenticate wcf service by username and password with ssl settings

http://blog.adnanmasood.com/2010/04/29/step-by-step-guide-for-authenticating-wcf-service-with-username-and-password-over-ssl/