Archive

Archive for the ‘C#’ Category

Authenticating users with the Belgium eID in ASP.NET

August 14, 2015 10 comments

Every Belgium resident has an eID card. This card functions as PKCS#11 keystore containing two X509 certificates (including their private keys): one for authentication and one for digital signing. These certificates are protected against a PIN/PUK code. The card can be used to authenticate the user in a web application using HTTPS with client certificate authentication. Because this mode of authentication makes use of two out of the three different types of information that can be used for authentication (something you know and something you have), it can be considered strong authentication.

In a classic HTTPS scenario, only the server will prove its identity to the user by making use of its X509 certificate, it is then up to the web application to do an authentication of the user in applicative code (over the secure SSL tunnel). With client certificate authentication, both the server and the user (in fact the browser) will prove their identity by making use of their X509 certificate.

eID authentication in ASP.NET

Authentication based on the Belgium eID card can be easily integrated into an ASP.NET web application. I have created the necessary code as an OWIN middleware component that can hooked into your web application and that will create a ClaimsIdentity representing the user. You can already find the source at Github (https://github.com/pieterderycke/Eid.Owin), but in the comming days I will also create a NuGet package for it.

The first thing you must do, is configure your web application to allow or require client certificates in IIS.

2015-08-04 19_54_32-Internet Information Services (IIS) Manager

2015-08-04 19_57_36-Internet Information Services (IIS) Manager

Once this is done, we can read out the client certificate in our OWIN middleware. There are a number of properties that can be parsed from the certificate. My code will create claims for all these properties

public class EidAuthenticationHandler : AuthenticationHandler
{
    protected override async Task AuthenticateCoreAsync()
    {
        var x509 = Context.Get("ssl.ClientCertificate");

        if (x509 != null)
        {
            ClaimsIdentity identity = ValidateX509Certificate(x509);
            return new AuthenticationTicket(identity, new AuthenticationProperties());
        }
        else
        {
            return new AuthenticationTicket(null, new AuthenticationProperties());
        }
    }

    private ClaimsIdentity ValidateX509Certificate(X509Certificate2 x509)
    {
        var chain = new X509Chain(true);
        chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
        chain.Build(x509);

        X509Certificate2 citizenCertificate = chain.ChainElements[0].Certificate;

        if (citizenCertificate.NotAfter  DateTime.Now)
            throw new Exception("The citizen certificate is not (longer) valid.");

        //TODO verify if citizen certificate has not been revoked

        if (chain.ChainElements[1].Certificate.Thumbprint != "74CC6E5559FFD7C2DD0526C0C21593C56C9384F3")
            throw new Exception("Invalid Citizen CA certificate.");

        if (chain.ChainElements[2].Certificate.Thumbprint != "51CCA0710AF7733D34ACDC1945099F435C7FC59F")
            throw new Exception("Invalid Belgium Root CA certificate.");

        string firstName = Regex.Match(citizenCertificate.Subject, "G=([^,]*),").Groups[1].Value;
        string lastName = Regex.Match(citizenCertificate.Subject, "SN=([^,]*),").Groups[1].Value;
        string nationalRegisterIdentificationNumber = Regex.Match(citizenCertificate.Subject, "SERIALNUMBER=([^,]*),").Groups[1].Value;
        string nationality = Regex.Match(citizenCertificate.Subject, "C=([^,]*)").Groups[1].Value;

        // Based on information of: https://www.ksz-bcss.fgov.be/nl/bcss/page/content/websites/belgium/services/docutheque/technical_faq/faq_5.html
        bool isMale = int.Parse(nationalRegisterIdentificationNumber.Substring(6, 3)) % 2 == 1;

        ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, firstName + " " + lastName, null, Options.AuthenticationType));
        identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName));
        identity.AddClaim(new Claim(ClaimTypes.Name, lastName));
        identity.AddClaim(new Claim(ClaimTypes.Gender, isMale ? "M" : "F"));
        identity.AddClaim(new Claim(ClaimTypes.Country, nationality));

        return identity;
    }
}

And for average Joe programer, this is super easy. All he/she has to add to his "Startup.Auth.cs" file is the following code and he/she can authenticate the users based on the eID card.

app.UseEidAuthentication(new EidAuthenticationOptions() 
{
	SignInAsAuthenticationType = "Cookies"
});
Categories: C#, eID

Jace.NET 0.9: your input is appreciated!

February 12, 2014 19 comments

Most of the last previous releases were limited and only introduced bug fixes or new mathematical functions. Jace.NET has already a complete support for all the standard math, but for the next release I have decided to increase the scope: from version 0.9 forward Jace.NET will have full support for matrices!

The following syntax is planned:

  • Definition of a matrix: A = [1,2,3;4,5,6;7,8,9]
  • Scalar multiplication: 3*A
  • Matrix multiplication: A*B
  • Transpose: A’ or transpose(A)
  • Select a matrix element: A[2,3]
  • New functions: ones(3,3), zeros(3,3)

For the initial 0.9.x release(s), I have foreseen the following constraints to simplify the initial support for matrices:

  • It will not be supported to use variables in matrix elements: so the following syntax will initially not be allowed: [1,2,3;4,var,6;7,8,9]
  • All matrix elements will be interpreted as doubles in the engine (not as integers)

And now comes the part where you are involved as a reader: I would really like have your input.

  • Would this satisfy you (matrix) needs?
  • Is the proposal ok?
  • Are the constraints acceptable?
  • Besides matrix support, what else would you like to see in Jace.NET?

Hope to hear from you guys! Smile

Categories: C#, Jace.NET

Changing the supported media types of the default media formatters in the ASP.NET Web API client library

January 15, 2014 Leave a comment

A couple of days ago, I encountered an issue when calling a REST service. The REST service was returning JSON data, but the content type in the HTTP header was set to “text/javascript”. This caused the default JSON formatter of the ASP.NET Web API client not to recognize the data (he expects “application/json”). It took me a while to find this proper solution as I wanted to avoid creating a custom formatter, but the ASP.NET Web API client library allows to modify the supported content types for the default content formatters.

HttpClient client = new HttpClient();

MediaTypeFormatterCollection formatters = new MediaTypeFormatterCollection();
formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));

HttpResponseMessage response = await client.GetAsync(url);
SearchResult result = await response.Content.ReadAsAsync(formatters);
Categories: ASP.NET Web API, C#, REST

Compiled Zip package for Jace 0.8.4

January 8, 2014 Leave a comment

Jace.NET is a mathematical calculation engine for .NET that can parse and execute strings containing mathematical formulas. More information on Jace can be found in previous articles published on this blog or in the following codeproject article: http://www.codeproject.com/Articles/682589/Jace-NET-Just-another-calculation-engine-for-NET.

Previously, the only way to obtain an already compiled version of Jace.Net was to use NuGet. Although I am still convinced that nowadays the recommended way to add frameworks to Visual Studio projects should be NuGet, I understand that this is not always possible. Especially in enterprise environments. For people in such situations, I have created a zip based version of Jace.NET. This zip package contains compiled versions of Jace for .NET 4.x, Windows Store, Windows Phone 7 and Windows Phone 8.

The zip version can be downloaded using the following link: https://github.com/pieterderycke/Jace/releases/download/0.8.4/Jace.0.8.4.zip.

All future zip packages will be published on the following GitHub page: https://github.com/pieterderycke/Jace/releases.

The assemblies in the zip package are currently not strongly signed. If you would rather prefer strongly singed assemblies, you can let me know by mail or by leaving a comment.

Categories: C#, Jace.NET

Jace.NET published on NuGet

November 10, 2012 Leave a comment

A couple of days ago, I have released the first version of my mathematical calculation engine for the .NET framework: Jace.NET. This build includes support for all the standard mathematical operations and a number of mathematical functions like: sin, cos, loge, logn, …

https://www.nuget.org/packages/Jace

You can also download a demo application, that gives a visual insight into the parsing and execution steps of Jace.NET:

http://sdrv.ms/UfyWXj

image

More information about the architecture of Jace.NET can found at:

https://pieterderycke.wordpress.com/2012/11/04/jace-net-just-another-calculation-engine-for-net/

https://github.com/pieterderycke/Jace

Categories: C#, Jace.NET

Jace.NET – Just another calculation engine for .NET

November 4, 2012 33 comments

I work as a .NET technical architect in the financial industry and I get in touch with all sorts of mathematical formulas representing insurance or banking products. Most of the time, these formulas are hard coded by programmers and are thus not very flexible to be change dynamically at runtime by end-users.

This inspired me to start developing a calculation engine for the .NET platform that can execute any mathematical formula stored as a string both with or without variables. I wiped the dust of my university book: “Modern compiler implementations” and started the development a couple of weeks ago. I decided to name the calculation engine Jace.NET: Just another calculation engine for .NET.

Jace.NET is designed to run on .NET 4.0, Windows Phone 7, Windows Phone 8 and Windows RT.

How to use it

Jace.NET can be used in a couple of ways:

By directly executing a given mathematical function using the provided variables:

Dictionary<string, double> variables = new Dictionary<string, double>();
variables.Add("var1", 2.5);
variables.Add("var2", 3.4);

CalculationEngine engine = new CalculationEngine();
double result = engine.Calculate("var1*var2", variables);

By building a .NET Func accepting a dictionary as input containing the values for each variable:

CalculationEngine engine = new CalculationEngine();
Func<Dictionary<string, double>, double> function = engine.Build("var1+2/(3*otherVariable)");

Dictionary<string, double> variables = new Dictionary<string, double>();
variables.Add("var1", 2);
variables.Add("otherVariable", 4.2);

double result = function(variables);

By building a typed .NET Func:

CalculationEngine engine = new CalculationEngine();
Func<int, double, double> function = (Func<int, double, double>)engine.Function("var1+2/(3*otherVariable)")
    .Parameter("var1", DataType.Integer)
    .Parameter("otherVariable", DataType.FloatingPoint)
    .Result(DataType.FloatingPoint)
    .Build();

double result = function(2, 4.2);

Architecture

Jace.NET has an architecture similar to the one of modern compilers: interpretation and execution are performed in a number of steps. Each step focuses on one aspect of the parsing and interpretation of the formula. This keeps the overall complexity manageable.

clip_image002

The process starts with the tokenizing phase. During this phase the input string is converted into the various allowed tokens: integers, doubles, operations and variables. If a part of the input string contains text that does not match with any type of token, an exception is thrown and Jace will halt.

When tokenizing is successfully finished, an abstract syntax tree (AST) is constructed. This abstract syntax tree is a tree like data model that unambiguously represents the mathematical formula in memory. All mathematical precedence rules are taking into account when constructing the abstract syntax tree. Jace uses an algorithm inspired by the shunting-yard algorithm of Dijkstra to create this AST.

clip_image004

After AST creation, the optimizer will try to simplify the abstract syntax tree: if a part of the formula does not depend on variables but solely on constants. This part of the tree is already calculated and replaced by a constant in the tree.

clip_image006

The final phase is the OpCode generation. During this phase, a .NET dynamic method is created and the necessary MSIL is generated to execute the formula. This dynamic method is cached in memory. If the same formula is executed again in the future with other values for the variables. The interpretation steps are skipped and the dynamic method is directly executed. If the formulas of the calculations are frequently reoccurring, Jace.NET has near compiled code performance.

GitHub

If you are interested in the source code, please have a look at:

http://github.com/pieterderycke/Jace

Categories: C#, Jace.NET

Logging all unhandled exceptions in WCF with Log4Net

September 5, 2012 2 comments

Scientific studies have shown that all applications contain a number of bugs. It is naïve to think that your applications would be bug free. When bugs occur is important that the necessary information gets logged to reproduce and fix the issues.

Assuring that all unhandled exceptions get logged in crucial. If you don’t now all the unhandled exceptions you will be blind for what happens in the production environment impacting your end-users. WCF produces the necessary hook to now when an unhandled exception has occurred in your services: the IErrorHandler. In this short article, I will demonstrate a simple implementation that logs these exceptions with Log4Net.

The most important component in this example is ofcourse the error handler implementation itself. The method “HandleError” gets called for every unhandled exception by the WCF stack. This method has to indicate with its return value if it has “handled” the exception or if it remains “unhandled”. In our implementation we just log it with Log4Net and indicate to WCF that it remains unhandled and has to pass the stack further.

public class Log4NetErrorHandler : IErrorHandler
{
    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    public bool HandleError(Exception error)
    {
        log.Error("An unexpected has occurred.", error);

        return false; // Exception has to pass the stack further
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    }
}

The only thing that remains now is to hook this IErrorHandler implementation into the WCF stack. To do this, we must implement a new service behavior. Below you can find the necessary code.

public class Log4NetServiceBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        IErrorHandler errorHandler = new Log4NetErrorHandler();

        foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
        {
            channelDispatcher.ErrorHandlers.Add(errorHandler);
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}

Next we must implement a Behavior Extension Element to this into WCF stack using the web.config or the app.config

public class Log4NetBehaviorExtensionElement : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof (Log4NetServiceBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new Log4NetServiceBehavior();
    }
}

Now we can declare in the config that WCF must use our custom service behavior extension.

<system.serviceModel>
<services>
<!-- We define our WCF Services ... -->
</service>
</services>

<behaviors>
<serviceBehaviors>
<behavior>
<log4net />
</behavior>
</serviceBehaviors>
</behaviors>

<extensions>
<behaviorExtensions>
<add name="log4net"
type="MyProject.Log4NetBehaviorExtensionElement, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
Categories: C#, WCF