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/

Monday, October 24, 2011

Commands In WPF

Commands In WPF
Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.

The simplest way to use a command in WPF is to use a predefined RoutedCommand from one of the command library classes; use a control that has native support for handling the command; and uses a control that has native support for invoking a command. The Paste command is one of the predefined commands in the ApplicationCommands class. The TextBox control has built in logic for handling the Paste command. And the MenuItem class has native support for invoking commands.
The following example shows how to set up a MenuItem so that when it is clicked it will invoke the Paste command on a TextBox, assuming the TextBox has keyboard focus

Four Main Concepts in WPF Commanding
1. The command is the action to be executed.
2. The command source is the object which invokes the command.
3. The command target is the object that the command is being executed on.
4. The command binding is the object which maps the command logic to the command.

Commands
Commands in WPF are created by implementing the ICommand interface. ICommand exposes two methods, Execute, and CanExecute, and an event, CanExecuteChanged.
Execute performs the actions that are associated with the command.
CanExecute determines whether the command can execute on the current command target.
CanExecuteChanged is raised if the command manager that centralizes the commanding operations detects a change in the command source that might invalidate a command that has been raised but not yet executed by the command binding.
The WPF implementation of ICommand is the RoutedCommand class and is the focus of this overview.
The main sources of input in WPF are the mouse, the keyboard, ink, and routed commands. The more device-oriented inputs use a RoutedEvent to notify objects in an application page that an input event has occurred. A RoutedCommand is no different. The Execute and CanExecute methods of a RoutedCommand do not contain the application logic for the command, but rather they raise routed events that tunnel and bubble through the element tree until they encounter an object with a CommandBinding. The CommandBinding contains the handlers for these events and it is the handlers that perform the command. For more information on event routing in WPF, see Routed Events Overview.
The Execute method on a RoutedCommand raises the PreviewExecuted and the Executed events on the command target. The CanExecute method on a RoutedCommand raises the CanExecute and PreviewCanExecute events on the command target. These events tunnel and bubble through the element tree until they encounter an object which has a CommandBinding for that particular command.
WPF supplies a set of common routed commands spread across several classes: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommands, and EditingCommands. These classes consist only of the RoutedCommand objects and not the implementation logic of the command. The implementation logic is the responsibility of the object on which the command is being executed on.

Command Sources
A command source is the object which invokes the command. Examples of command sources are MenuItem, Button, and KeyGesture.
Command sources in WPF generally implement the ICommandSource interface.

Command Binding
A CommandBinding associates a command with the event handlers that implement the command.
The CommandBinding class contains a Command property, and PreviewExecuted, Executed, PreviewCanExecute, and CanExecute events.
Command is the command that the CommandBinding is being associated with. The event handlers which are attached to the PreviewExecuted and Executed events implement the command logic. The event handlers attached to the PreviewCanExecute and CanExecute events determine if the command can execute on the current command target.
The following example shows how to create a CommandBinding on the root Window of an application. The CommandBinding associates the Open command with Executed and CanExecute handlers.


A CommandBinding is attached to a specific object, such as the root Window of the application or a control. The object that the CommandBinding is attached to defines the scope of the binding. For example, a CommandBinding attached to an ancestor of the command target can be reached by the Executed event, but a CommandBinding attached to a descendant of the command target cannot be reached. This is a direct consequence of the way a RoutedEvent tunnels and bubbles from the object that raises the event.
In some situations the CommandBinding is attached to the command target itself, such as with the TextBox class and the Cut, Copy, and Paste commands. Quite often though, it is more convenient to attach the CommandBinding to an ancestor of the command target, such as the main Window or the Application object, especially if the same CommandBinding can be used for multiple command targets. These are design decisions you will want to consider when you are creating your commanding infrastructure.
Command Target
The command target is the element on which the command is executed. With regards to a RoutedCommand, the command target is the element at which routing of the Executed and CanExecute starts. As noted previously, in WPF the CommandTarget property on ICommandSource is only applicable when the ICommand is a RoutedCommand. If the CommandTarget is set on an ICommandSource and the corresponding command is not a RoutedCommand, the command target is ignored.
The command source can explicitly set the command target. If the command target is not defined, the element with keyboard focus will be used as the command target. One of the benefits of using the element with keyboard focus as the command target is that it allows the application developer to use the same command source to invoke a command on multiple targets without having to keep track of the command target. For example, if a MenuItem invokes the Paste command in an application that has a TextBox control and a PasswordBox control, the target can be either the TextBox or PasswordBox depending on which control has keyboard focus.


The CommandManager

The CommandManager serves a number of command related functions. It provides a set of static methods for adding and removing PreviewExecuted, Executed, PreviewCanExecute, and CanExecute event handlers to and from a specific element. It provides a means to register CommandBinding and InputBinding objects onto a specific class. The CommandManager also provides a means, through the RequerySuggested event, to notify a command when it should raise the CanExecuteChanged event.
The InvalidateRequerySuggested method forces the CommandManager to raise the RequerySuggested event. This is useful for conditions that should disable/enable a command but are not conditions that the CommandManager is aware of.






Command Library

________________________________________
WPF provides a set of predefined commands. The command library consists of the following classes: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommands, and the ComponentCommands. These classes provide commands such as Cut, BrowseBack and BrowseForward, Play, Stop, and Pause.





ICommand Interface implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace DelegateCommandPattern
{
///
/// DelegateCommand Class implements ICommand Interface to Create Commands for wpf application which uses MVVM Pattern.
/// Commands in WPF are created by implementing the ICommand interface.
///

public class DelegateCommand : ICommand
{
public delegate void ExecuteCommand(object parameter);
public delegate bool CanExecuteCommand(object parameter);

ExecuteCommand _execute;
CanExecuteCommand _canExecute;

public DelegateCommand(ExecuteCommand target, CanExecuteCommand canExecute)
{
_execute = target;
_canExecute = canExecute;
}

public DelegateCommand (ExecuteCommand target)
{
_execute = target;
}

#region IComamnd Implementation

///
/// CanExecuteChanged is raised if the command manager that centralizes the commanding
/// operations detects a change in the command source that might invalidate a command
/// that has been raised but not yet executed by the command binding.
///

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

///
/// This method determines whether the command can execute on the current target.
/// Normally, if the command cannot execute, the command source(like button and etc) disables itself.
///

///
///
public bool CanExecute(object parameter)
{
if (_canExecute == null)
return true;

return _canExecute.Invoke(parameter);
}

///
/// This method performs the actions that are associated with the command.
///

///
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
}
}