I've written some code that reflections MethodInfo objects from a type using its name and signature. This has been working well and all unit tests have passed, until now.
Consider the following code:
internal interface IBaseInterface
{
void GetSomething();
}
internal interface IDerivedInterface : IBaseInterface
{
void DoSomethingElse();
}
Does interface inheritance exist?
Much to my amazement, the answer is no, at least according to reflection. This is completely not what I had assumed.
Does it matter? Normally, probably not. The reason is that most people are dealing with concrete types. As concrete types provide implementations of the methods that are defined by their interfaces, the type correctly returns the expected MethodInfo objects from Type.GetMethods().
Interfaces behave very differently. If you call Type.GetMethods() on IDerivedInterface then you will be missing the methods defined in IBaseInterface. I expected that IDerivedInterface had a base type of IBaseInterface and inherited its methods. I made this assumption because that is the affect that IDerivedInterface has on types that implement it. There is an inheritance behaviour as the concrete type must implement methods for both interfaces.
What is interesting is that IDerivedInterface doesn't have a base type, and Type.GetMethods() doesn't return IBaseInterface methods. IDerivedInterface does however indicate that it implements the IBaseInterface interface.
Now things get a little curly here. An interface that implements an interface doesn't need to provide any implementation (it can't, its an interface) or do anything to satisfy implementing the interface. This makes me think that interfaces neither implement other interfaces, or inherit from them.
Here is the complete source:
using System;
using System.Reflection;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
// _______________________________________________________
//
// Base Interface test
// _______________________________________________________
Type baseInterfaceTest = typeof(IBaseInterface);
// This returns 1 method
MethodInfo[] baseInterfaceMethods = baseInterfaceTest.GetMethods();
// This returns false
Boolean baseInterfaceHasBaseClass = baseInterfaceTest.BaseType != null;
// This returns null
Type[] baseInterfaceInterfaces = baseInterfaceTest.GetInterfaces();
// _______________________________________________________
//
// Derived Interface test
// _______________________________________________________
Type derivedInterfaceTest = typeof(IDerivedInterface);
// This will only return 1 method
MethodInfo[] derivedInterfaceMethods = derivedInterfaceTest.GetMethods();
// This returns false
Boolean derivedInterfaceHasBaseClass = derivedInterfaceTest.BaseType != null;
// This returns 1 interface type
Type[] derivedInterfaceInterfaces = derivedInterfaceTest.GetInterfaces();
// _______________________________________________________
//
// Derived Type test
// _______________________________________________________
Type derivedTypeTest = typeof(DerivedType);
// This will return 2 methods (in addition to the 4 from System.Object)
MethodInfo[] derivedTypeMethods = derivedTypeTest.GetMethods();
// This will return true (System.Object)
Boolean derivedTypeHasBaseClass = derivedTypeTest.BaseType != null;
// This returns 2 interface type
Type[] derivedTypeInterfaces = derivedTypeTest.GetInterfaces();
}
}
internal interface IBaseInterface
{
void GetSomething();
}
internal interface IDerivedInterface : IBaseInterface
{
void DoSomethingElse();
}
internal class DerivedType : IDerivedInterface
{
public void DoSomethingElse()
{
}
public void GetSomething()
{
}
}
}
I had a bit of a slipup yesterday. I had a set of changes that I was relating to two different work items. I realised that I really should split up the check-in into two check-ins so that the code files are better related to their work items. What I didn't do before checking in both changesets was updating the comments of the check-ins before I committed them.
After realising my mistake, I wondered if I could change the comment of a changeset. Thankfully the answer is yes. After finding the changesets by looking at the history in TFS, I was able to simply adjust the comment to be more appropriate to the changeset and click Save. Simple.
I've just hit the foreach code coverage issue again in one of my unit tests (see my Code coverage doesn't like foreach loops post). To ensure that my tests were correctly covering all possibilities, I had to change the foreach loop into a for loop and run the test again.
The issue in this case is that the collection object I was referencing was ConfigurationElementCollection which implements ICollection. Unfortunately, this type doesn't expose an indexer property. In order to test the code coverage metrics using a for loop, I first had to create an array of the appropriate length and copy across the items across.
After running the test again, I had 100% code coverage. I have now confirmed that the missing blocks in coverage are a result of the foreach statement rather than an issue with my unit test. Now the question is do I remove the additional code and redundant array copy ? The reasons to convert the code back to the foreach loop are:
- Cleaner code
- Less bloat
- More understandable
- Code coverage shouldn't define coding style
The second point is guaranteed to get some people in a flap. To be clear, I am not saying that testability shouldn't have a bearing on coding style, I'm saying that code coverage shouldn't define coding style. While this post is about code coverage, I should also point out that code coverage doesn't really mean much by itself. It is just an indicator.
In this case, the unit tests were valid and covered all the angles, so the question is purely whether a code coverage metric is important enough to modify the code.
Another thing also comes to mind. What about performance? By using the array, I have the additional overhead of creating an array and populating it from the ICollection, but then I have the performance gain from not using the IEnumerator invoked by the foreach statement.
A quick test gave me a suitable answer.
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
Collection<String> items = new Collection<String>();
for (Int32 index = 0; index < 10; index++)
{
items.Add(Guid.NewGuid().ToString());
}
Stopwatch watch = new Stopwatch();
const Int32 Iterations = 10000;
Thread.Sleep(1000);
watch.Start();
for (Int32 index = 0; index < Iterations; index++)
{
foreach (String item in items)
{
Debug.WriteLine(item);
}
}
watch.Stop();
Console.WriteLine("foreach took {0} ticks", watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (Int32 index = 0; index < Iterations; index++)
{
String[] newItems = new String[items.Count];
items.CopyTo(newItems, 0);
for (Int32 count = 0; count < newItems.Length; count++)
{
Debug.WriteLine(newItems[count]);
}
}
watch.Stop();
Console.WriteLine("for took {0} ticks", watch.ElapsedTicks);
Console.ReadKey();
}
}
}
Each time I run this test, the for loop runs at 70% of the time of the foreach loop, even with the array copy.
While code coverage by itself is not enough to make me change my coding style, a performance improvement and more accurate code coverage is a good enough reason.
Here's a tip for young players. You may find that getting the latest WiX 3.0 beta from here gives you an error saying that you need to have a version of Visual Studio installed that is above the Express edition. I have Team Suite installed, so it should be a problem. After lots of research, I came across this post which gave me the answer. It wasn't a problem with the version of Visual Studio that I had installed, it was because latest build published on the SourceForge download page was prior to their support of x64 systems. After downloading the latest build published here, it's all good.
One of my most used feature in the 3.5 compiler for .Net is automatic properties. In case you are not familiar, here is a recap.
Traditionally, properties work with a backing field. For example:
private String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set
{
_someValue = value;
}
}
Automatic properties under the 3.5 compiler allow this code to be represented as:
public String SomeValue
{
get;
set;
}
Automatic properties make code cleaner and easier to use. Additionally, they also require less testing. There isn't any point testing their logic of accessing the backing field to ensure correct operation and they appear with 100% code coverage. My biggest gripe though is that they don't truly support readonly definitions.
The documentation on MSDN says:
Auto-implemented properties must declare both a get and a set accessor. To create a readonly auto-implemented property, give it a private set accessor.
The implementation of automatic properties by the compiler define that readonly automatic properties are achieved by assigning a private scope to the set accessor. For example:
public String SomeValue
{
get;
private set;
}
Unfortunately, I think this is a cheap bandaid hack. It doesn't make the property truly readonly. It is technically readonly, but only from the perspective of external callers. Internal to the class, the property is not readonly because the private scope makes setting the property value possible. This doesn't protect the value of the backing field which is what a true readonly property should be able to support. See here for the MSDN documentation on the readonly keyword.
I would like to see this changed. Without understanding the complexities of writing compilers, I would think that this change would not be too significant. The simple fix would be to enhance the syntax of the automatic property setter definition. If the private set statement could be enhanced to understand a readonly keyword, then the compile could mark the backing field with the same readonly keyword. For example:
public String SomeValue
{
get;
private readonly set;
}
This would then be interpreted by the compiler as something like this:
private readonly String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set
{
_someValue = value;
}
}
I have added this as a suggestion to Microsoft Connect here.
I have been pulling my hair out this afternoon trying to figure out why my code is performing so badly in a load test. After playing with the code and running a lot of tests, I didn't have any answers until I looked at my testrunconfig file. Code coverage was the first thing I looked at.
With code coverage turned on, the report looked like this.
After I turned code coverage off, I was much happier.
The Test Response Time graphs (top right) highlight the difference between the test run performance as does the the CPU usage (red line in the bottom right graph). Of the four tests, the one that is doing the most work was averaging 6.76 seconds per test with code coverage which is atrocious. Without code coverage, this test was running an average of 0.00024 seconds per test. Just a little different.
Updated: Changed images so they are more readable and changed the scale of the Test Response Time graph so the difference of the tests can be seen.
I read Patrick Smacchia's post this morning about a simple trick to code better and to increase testability and found it to be a great argument. These are the kinds of posts that I really enjoy reading and thinking about. They often have me hacking up test projects to flesh out ideas or kicking off Reflector to see what the BCL is doing.
This was a good post because it got me to challenge why I am coding in the particular style that I have. I have always been a fan of combining if tests when it doesn't result in overly complex logic. In this case, Patrick is arguing that such a style of coding increases nesting depth and makes testing harder.
Take this test case based on his post:
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApplication1
{
internal class Program
{
public static void MethodA(List<String> list)
{
foreach (String item in list)
{
if (item == null || item.Length == 0
|| item.Contains("a"))
{
continue;
}
Console.Write(String.Empty);
}
}
public static void MethodB(List<String> list)
{
foreach (String item in list)
{
if (item == null)
{
continue;
}
if (item.Length == 0)
{
continue;
}
if (item.Contains("a"))
{
continue;
}
Console.Write(String.Empty);
}
}
private static void Main(String[] args)
{
List<String> items = new List<String>(100);
for (Int32 index = 0; index < 100; index++)
{
items.Add(index.ToString());
}
Stopwatch watch = new Stopwatch();
watch.Start();
for (Int32 firstLoop = 0; firstLoop < 100000; firstLoop ++)
{
MethodA(items);
}
watch.Stop();
Int64 firstTickCount = watch.ElapsedTicks;
watch.Reset();
watch.Start();
for (Int32 secondLoop = 0; secondLoop < 100000; secondLoop++)
{
MethodB(items);
}
watch.Stop();
Int64 secondTickCount = watch.ElapsedTicks;
Console.WriteLine(firstTickCount);
Console.WriteLine(secondTickCount);
Console.WriteLine(secondTickCount - firstTickCount);
Console.ReadKey();
}
}
}
MethodA contains the combined if tests while MethodB separates them out into individual tests. While I'm not sure about the nesting depth argument due to compiler optimizations, I totally agree about the increase in testability. I also think that such a coding style is much more readable. The risk of combined if tests is that they quickly become complex and difficult to understand.
The first question I had about this was what is the impact on compiled code? Does this change impact performance? After writing up the above test case, I found that it doesn't (as unscientific as the test case is). The next step was to check out the difference in the IL. Turns out that both methods have exactly the same IL. This would explain the similar performance results. I say similar because there would be many outside influences that would result in slightly different outcomes.
So performance isn't a problem as the compiler optimizes the code. The code is more readable and there is no risk of getting confused about the combination of if statements. It is also, as Patrick argues, more testable. The individual continue statements will not get covered if the related scenario of an if statement is not tested for. On this point however, Visual Studio will highlight the line as partially tested rather than 100% covered, but doesn't help in telling you which part of the statement wasn't covered. This makes this style more testable as it is completely clear what hasn't been tested.
I'm no IL expert, but it is interesting that the compiler seems to choose the more complex version (at least to Reflectors interpretation). The following is Reflectors decompilation of the release build interpreted in C#.
public static void MethodB(List<string> list)
{
foreach (string item in list)
{
if (((item != null) && (item.Length != 0)) && !item.Contains("a"))
{
Console.Write(string.Empty);
}
}
}
I think I have a new change to my coding style.
I have been working on a CodePlex project over the last month or so that contains a set of extensibility tools. I have just released ReflectorLink 1.0 which is a Visual Studio addin that launches Reflector.
The following is a copy of the Using ReflectorLink 1.0 documentation on the project site.
ReflectorLink is a Visual Studio addin that launches Reflector. Before launching Reflector, it checks to see whether Reflector is already running. If it does find Reflector already running, it will set it as the active application. If Reflector is not found, it will be started (assuming it can be found). After Reflector has been activated/started, additional commands may be sent to it to load assemblies.
ReflectorLink can be invoked from the Tools menu, Solution Explorer context menus or the code document context menu.
Tools menu
Click the Tools menu and select Reflector.

When launching Reflector from the Tools menu, Reflector will be launched with no further action if no solution is loaded. If there is a solution loaded, the binary references of each project will be loaded into Reflector.
Code document
Right-click on a code document and select Reflector.

When launching Reflector from the code document, ReflectorLink will determine if there is a related project that has binary references. Any references found will be loaded into Reflector.
Note: ReflectorLink does not yet support resolving items clicked in the code document. Only the related project is used to determine what to load into Reflector.
Solution Explorer
There are several scenarios where Reflector can be launched in Solution Explorer. These are:
- Solution node
- Project node
- Project References node
- Project Reference node
- Solution Items
In each scenario, the Reflector menu item will only be enabled if binary references can be found. For solution items, the menu item will only be displayed if the solution item selected is an exe or dll file.
Solution node
Right-click on the solution node and select Reflector.

When launching Reflector from a solution node, ReflectorLink will determine the set of binary references for each project in the solution. Any references found will be loaded into Reflector.
Project node
Right-click on a project node and select Reflector.

When launching Reflector from a project node, ReflectorLink will determine the set of binary references for the project. Any references found will be loaded into Reflector.
Project References node
Right-click on the References node in a project and select Reflector.

When launching Reflector from a References node, ReflectorLink will determine the set of binary references for the related project. Any references found will be loaded into Reflector.
Project Reference node
Right-click on a reference node in a project and select Reflector.

When launching Reflector from a reference node, ReflectorLink will determine whether the reference is a binary reference or a project reference. The menu item will be enabled if the reference is a binary reference and will load it into Reflector when launched.

If the reference is a project reference, the menu item will be disabled.
Solution Item node
Right-click on a solution item node that is an exe or dll and select Reflector.

When launching Reflector from a solution item node, ReflectorLink will determine whether the item is an exe or dll file. The menu item will be invisible if the item is not an exe or dll. The selected item will be loaded into Reflector when launched.
ReflectorLink 1.0 can be downloaded from here.
I have written a few addins over the last couple of years and I have always found the object model really painful to deal with. One of the more common problems I have encountered is trying to identify the type of UIHierarchyItem.Object. This is especially common when you deal with the contents of the Solution Explorer window.
I only know of one solution for identifying the real type behind the object. You can make a call out to Microsoft.VisualBasic.Information.TypeName(Object) to attempt to resolve the type. This wasn't always successful and was also a little limited as the object often implements multiple types. I realised that there was a very easy and more comprehensive way of figuring out what types were being implemented.
By using this DebugHelper class in your addin solution, you will be able to figure out the object types. The Conditional attribute ensures that these methods (and calls to them) will not appear in your release build. The method takes a UIHierarchyItem and searches all the publicly available types of all the assemblies in the app domain for types that are implemented by the UIHierarchyItem.Object property.
using System;
using System.Diagnostics;
using System.Reflection;
using EnvDTE;
namespace Neovolve.Extensibility.VisualStudio
{
/// <summary>
/// The <see cref="DebugHelper"/>
/// class is used to help with debugging tasks for Visual Studio addin development.
/// </summary>
/// <remarks>
/// This class was created by Rory Primrose for the
/// <a href="http://www.codeplex.com/NeovolveX" target="_blank">NeovolveX</a>
/// project.
/// </remarks>
public static class DebugHelper
{
/// <summary>
/// Identifies the internal object types.
/// </summary>
/// <param name="item">The item.</param>
[Conditional("DEBUG")]
public static void IdentifyInternalObjectTypes(UIHierarchyItem item)
{
if (item == null)
{
Debug.WriteLine("No item provided.");
return;
}
if (item.Object == null)
{
Debug.WriteLine("No item object is available.");
return;
}
// Loop through all the assemblies in the current app domain
Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
// Loop through each assembly
for (Int32 index = 0; index < loadedAssemblies.Length; index++)
{
// Assume that the assembly to check against is EnvDTE.dll
IdentifyInternalObjectTypes(item, loadedAssemblies[index]);
}
}
/// <summary>
/// Identifies the internal object types.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="assemblyToCheck">The assembly to check.</param>
[Conditional("DEBUG")]
public static void IdentifyInternalObjectTypes(UIHierarchyItem item, Assembly assemblyToCheck)
{
// Get the types that are publically available
Type[] exportedTypes = assemblyToCheck.GetExportedTypes();
// Loop through each type
for (Int32 index = 0; index < exportedTypes.Length; index++)
{
// Check if the object instance is of this type
if (exportedTypes[index].IsInstanceOfType(item.Object))
{
Debug.WriteLine(exportedTypes[index].FullName);
}
}
}
}
}
Using this debug helper method saved hours if not days in fixing this problem. I hope this helps other people as well.
When it is a EnvDTE.ProjectItem. I must admit that this one took me by surprise.
I am writing a Visual Studio addin for launching Reflector (see the CodePlex project here). You can launch Reflector from the tools menu and the Solution Explorer window and code document context menus. This issue came about when I found a bug in my addin while doing some testing. The scenario encountered was that the binary references for projects in Solution Explorer (the Project node and References node) were not resolved. I had tested this feature in another solution successfully and noticed that the difference between the solutions was that the one with the bug had the projects in solution folders.
After doing some debugging, it turns out that when a project is contained in a solution folder, the UIHierarchyItem.Object value exposed through Solution Explorer is no longer represented by an EnvDTE.Project. It is now an EnvDTE.ProjectItem. Ironically, you must reference ProjectItem.SubProject to get access to the project.
The fact that the project is a project items sub project because its parent is a folder in Solution Explorer is totally confusing.
I have upgraded the blog to CS2008 tonight. It mostly went well, but I did waste an hour trying to get my media files to be served. Turned out that the issue was that the AppPool in IIS now needs to be run under Integrated rather than Classic. See here.
My dad bought a laptop that came with the typical factory image full of junk. It crashed constantly, didn't detect the anti-virus that was installed and wouldn't allow me to activate Windows Defender. It also only had the system partition for data. All good reasons for a rebuild. HP kindly don't offer media for recovery though. Not being familiar with this, I wiped the system drive for a rebuild without first burning the recovery partition to a DVD. After lots of attempts at recovery and installation, one of my actions was to set the recovery partition as the active partition so I could boot straight into it. That worked until the recovery image wanted to reboot, then I couldn't set the active partition back.
I miss the days when manufacturers would just include a couple of DVD's. Are they really that expensive to press that they can't include the disks?
Any way, Ultimate Boot CD became a lifeline.
There are cases when you need to transmit username/password credentials to WCF without transport security. The times that you should do this are rare because of the obvious security implications of sending credentials over the wire without encryption. One case where this is required is where hardware acceleration is used in a load balancer. The traffic between the load balancer and the client is encrypted, but the traffic between the load balancer and the service host is not. The issue here is that the service still needs the credentials passed to the load balancer from the client.
Drew Marsh has a great write up about how to lie to WCF about the security of the binding that it is using for a service. Nicholas Allen has also posted on the topic here and here.
A common problem with service security is that username/password security is needed for authentication and authorization at the service boundary, but those same credentials are also required to consume other resources such as a database or underlying service. By default, username/password security will run the authentication and authorization of the credentials but only the username is available to the executing service code. This is typically made available through Thread.CurrentPrincipal.Identity.Name.
Storing username password credentials in a custom principal and identity against Thread.CurrentPrincipal is a really nice way of going. Thread.CurrentPrincipal returns IPrincipal which is a common framework type that will be available to all layers of a service executed by the thread. If Thread.CurrentPrincipal.Identity can return a custom IIdentity, then this is where the password can be made available. Using Thread.CurrentPrincipal frees up business and data access layers from relying on any security design that is tied up with a specific service implementation. The trick is how to get username password information into the thread that executes the service code.
One place that both the username and password is available is in the UserNamePasswordValidator.Validate() method. You could write a custom validator and hook it up in your service configuration, but this doesn't help you. There is no native facility to store the password from the validator. You can't store any credentials against Thread.CurrentPrincipal as the validator gets evaluated by WCF on a different thread than the thread that executes the service code. You could manually put it somewhere like in a static collection, but this would have potential security risks as your code will be handling the safety and security of multiple sets of credentials for users. This also means that somewhere else in the service implementation would require the credentials to be pulled out of the static and put into Thread.CurrentPrincipal. Using validators for this purpose is not the answer. Validators are for validating credentials, not storing them for later use.
Thankfully, there is a much more elegant way of passing these credentials around compared to the validator based solution. There is another place in WCF where there is access to both the username and the password and the security context of the service. Leveraging WCF extensibility is the answer.
Setting up the security context of the service is done using IAuthorizationPolicy implementations. The place in WCF where there is access to the username, password and IAuthorizationPolicy configuration is CustomUserNameSecurityTokenAuthenticator.ValidateUserNamePasswordCore. The ValidateUserNamePasswordCore method is passed the username and password parameters and returns a readonly collection of IAuthorizationPolicy objects. SecurityTokenAuthenticator, from which CustomUserNameSecurityTokenAuthenticator ultimately inherits from, is not configurable in WCF itself. Using Reflector to follow the calls against SecurityTokenAuthenticator, the place that is extensible in WCF such that a custom SecurityTokenAuthenticator can be used is ServiceCredentials. Creating a custom ServiceCredentials object, using custom objects between the ServiceCredentials and SecurityTokenAuthenticator call stack is the answer.
PasswordServiceCredentials
The custom ServiceCredentials class implementation returns a custom SecurityTokenManager if custom username password validation is enabled.
public class PasswordServiceCredentials : ServiceCredentials
{
public PasswordServiceCredentials()
{
}
private PasswordServiceCredentials(
PasswordServiceCredentials clone)
: base(clone)
{
}
protected override ServiceCredentials CloneCore()
{
return new PasswordServiceCredentials(this);
}
public override SecurityTokenManager CreateSecurityTokenManager()
{
// Check if the current validation mode is for custom username password validation
if (UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidationMode.Custom)
{
return new PasswordSecurityTokenManager(this);
}
Trace.TraceWarning(Resources.CustomUserNamePasswordValidationNotEnabled);
return base.CreateSecurityTokenManager();
}
}
PasswordSecurityTokenManager
The custom SecurityTokenManager returns a custom SecurityTokenAuthenticator when it finds a SecurityTokenRequirement for username security. It also ensures that a default validator is available if one is not configured.
internal class PasswordSecurityTokenManager : ServiceCredentialsSecurityTokenManager
{
public PasswordSecurityTokenManager(
PasswordServiceCredentials credentials)
: base(credentials)
{
}
public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
{
if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
{
outOfBandTokenResolver = null;
// Get the current validator
UserNamePasswordValidator validator =
ServiceCredentials.UserNameAuthentication.CustomUserNamePasswordValidator;
// Ensure that a validator exists
if (validator == null)
{
Trace.TraceWarning(Resources.NoCustomUserNamePasswordValidatorConfigured);
validator = new DefaultPasswordValidator();
}
return new PasswordSecurityTokenAuthenticator(validator);
}
return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
}
}
PasswordSecurityTokenAuthenticator
The custom SecurityTokenAuthenticator is where the half of the magic happens. Here there is the opportunity to return custom a IAuthorizationPolicy implementation that will allow us to inject a custom IPrincipal and IIdentity on the thread the executes the service code.
internal class PasswordSecurityTokenAuthenticator : CustomUserNameSecurityTokenAuthenticator
{
public PasswordSecurityTokenAuthenticator(
UserNamePasswordValidator validator)
: base(validator)
{
}
protected override ReadOnlyCollection<
IAuthorizationPolicy> ValidateUserNamePasswordCore(
String userName,
String password)
{
ReadOnlyCollection<IAuthorizationPolicy> currentPolicies = base.ValidateUserNamePasswordCore(
userName, password);
List<IAuthorizationPolicy> newPolicies = new List<IAuthorizationPolicy>(currentPolicies);
newPolicies.Add(new PasswordAuthorizationPolicy(userName, password));
return newPolicies.AsReadOnly();
}
}
PasswordAuthorizationPolicy
The IAuthorizationPolicy implementation is where the other half of the magic happens. This policy gets passed the username and password so that it can store the password in the security context. The policy will return false until it finds a GenericIdentity in the evaluation context that has the same username as the one provided to the policy. It then creates a custom IIdentity that exposes both the username and password and stores it back into the collection of identities in the evaluation context and also stores it against the PrimaryIdentity property. PrimaryIdentity is then exposed through ServiceSecurityContext.PrimaryIdentity in the service implementation. A custom principal is then created (without roles) and stores it against the Principal property of the context. Principal is then injected into Thread.CurrentPrincipal by WCF (depending on configuration).
using System;
using System.Collections.Generic;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.Security.Principal;
using System.ServiceModel;
using System.Threading;
namespace Neovolve.Framework.Communication.Security
{
internal class PasswordAuthorizationPolicy : IAuthorizationPolicy
{
public PasswordAuthorizationPolicy(
String userName,
String password)
{
const String UserNameParameterName = "userName";
if (String.IsNullOrEmpty(userName))
{
throw new ArgumentNullException(UserNameParameterName);
}
Id = Guid.NewGuid().ToString();
Issuer = ClaimSet.System;
UserName = userName;
Password = password;
}
public bool Evaluate(
EvaluationContext evaluationContext,
ref object state)
{
const String IdentitiesKey = "Identities";
// Check if the properties of the context has the identities list
if (evaluationContext.Properties.Count == 0
|| evaluationContext.Properties.ContainsKey(IdentitiesKey) == false
|| evaluationContext.Properties[IdentitiesKey] == null)
{
return false;
}
// Get the identities list
List<IIdentity> identities = evaluationContext.Properties[IdentitiesKey] as List<IIdentity>;
// Validate that the identities list is valid
if (identities == null)
{
return false;
}
// Get the current identity
IIdentity currentIdentity =
identities.Find(
identityMatch =>
identityMatch is GenericIdentity
&& String.Equals(identityMatch.Name, UserName, StringComparison.OrdinalIgnoreCase));
// Check if an identity was found
if (currentIdentity == null)
{
return false;
}
// Create new identity
PasswordIdentity newIdentity = new PasswordIdentity(
UserName, Password, currentIdentity.IsAuthenticated, currentIdentity.AuthenticationType);
const String PrimaryIdentityKey = "PrimaryIdentity";
// Update the list and the context with the new identity
identities.Remove(currentIdentity);
identities.Add(newIdentity);
evaluationContext.Properties[PrimaryIdentityKey] = newIdentity;
// Create a new principal for this identity
PasswordPrincipal newPrincipal = new PasswordPrincipal(newIdentity, null);