Wednesday, February 26, 2014

WCF : The page you are requesting cannot be served because of the extension configuration

This is for WCF on Windows Server 2012.

Trying to access a svc URL and get:

"The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map."


The solution is:

Server Manager --> Add roles and features --> Features --> .NET Framework 4.5 Features --> WCF Services --> enable HTTP Activation.

Enjoy!

Thursday, February 13, 2014

Visual Basic : A VB claims-enabled application

There was a question over at the MSDN forum that intrigued me so I thought I would take a crack at it.

The question was: "Looking at the ADFS sdk I found ClaimsAwareWebsite in C#. Is there an example in VB.net as well?".

Disclaimer - the last time I used VB was many, many moons ago.

Ok - so ADFS is the same, WIF is the same, the .NET Framework is the same so it shouldn't be that difficult - right?

I used VS 2012 with "Identity and Access Tool" added.

Take a look here: How To: Build Claims-Aware ASP.NET Application Using Forms-Based Authentication.

OK so we create a new project but select "Other languages / Visual Basic / Web. Then select "ASP.NET Web Forms Application". You could go MVC - I'm more at home with Forms (Yeah - I know :-) ).

OK, that gives us the base project. Now use the "Identity and Access Tool" to "bind" your application to ADFS or wherever. Many references of the web to do this - it's language agnostic. And remember to add your new application as a RP in ADFS.

When you run up your application, you should be prompted for the logon screen.

Sweet!

Now in Step 2 in the above link, add the html exactly as described to Default.aspx.

Remember F7 / Shift F7 swops between code and designer.

You can convert the C# code-behind in Step 2 to VB using e.g. Convert C# to VB.NET .

My page (for reference) was:

------------------------------

Imports System.Web.UI
Imports System.Security.Claims

Public Class _Default
    Inherits Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load

        Dim claimsPrincipal As ClaimsPrincipal = TryCast(Page.User, ClaimsPrincipal)

        If claimsPrincipal IsNot Nothing Then
            Me.ClaimsGridView.DataSource = claimsPrincipal.Claims
            Me.ClaimsGridView.DataBind()
        End If

    End Sub
End Class

---------------------------

After you have been redirected to the home page after logging in, you should see a table that includes the Issuer, OriginalIssuer, Type, Value, and ValueType claims information about your account.

Enjoy!

Friday, January 31, 2014

LINQPad : debugging with Visual Studio

I've been a fan of LINQPad for a while and I use it a lot for writing code snippets and testing them.

Note: If you pay for it, you get Intellisense as well.

Came across a situation where I had a bug and couldn't put my finger on it. Would be ideal to debug / step-through it but you can't ...

Well, actually you can - learn something new every day.

Add these lines to your snippet:

Debugger.Launch();
Debugger.Break();

So obviously LINQPad is running
Start up Visual Studio - the normal Start screen is fine
Debug - Attach to Process
Select LINQPad.exe from the list and Attach
Run your snippet

BINGO - jumps into VS - debug away.

How have I not known about this?

Enjoy!

Wednesday, January 29, 2014

AD : PrincipalOperationException A device attached to the system is not functioning

Best error message ever.

Got this on a web site - WTF - what device?

Card reader, CD drive ... not on a web site, mate!

Turns out this is during a create on a user or a group in AD where the name is greater than the allowed field length.

So for Create User - the SAMAccountName can't be greater than 20 characters,

There's probably a similar restriction for  group since I got the same error.

Good interview question :-)

Enjoy!

Friday, January 17, 2014

Misc : How much is my blog worth?

Came across this site:

Worth of Web Calculator

According to this, my blog is worth the princely sum of $69.00 !

Any offers :-)

Enjoy!

ADFS : Multi-valued attributes from AD

There are two kinds of attributes in AD viz. single valued and multi-valued. The latter obviously can have more than one value.

You can see the difference when you try and edit them. Single-valued has a single textbook while multi-valued has a textbox to enter a new value and a multi-line textbox to show all the current values.

If you look at a multi-valued attribute in AD using ADUC, you'll see it displayed as:

value1;value2;value3

Note: This is different to a single value attribute that contains the string:

value1 value2 value3

That's a string of ONE value which is"value1 value2 value3".

How do you find them.

Use ldp, click on the Base DN of "CN=Schema ..." and then run:

(isSingleValued=FALSE)

I couldn't find any under the "objectClass=user" category but there are some if you have added the AD extension attributes to the schema i.e. the ones that start with "msExch ...".

All of which is a segue into how ADFS handles this. It produces a new claim (of the same type) for each value.

So if you took the above and mapped them to a claim of type Values, you'll get:

.../claim/Value =  value3
.../claim/Value =  value2
.../claim/Value =  value1

Interestingly, it seems to display the values in reverse order but I wouldn't make any assumptions about the order the claims are presented.

Enjoy!




Monday, January 13, 2014

Misc : MSDN 2000 points!

Finally passed the 2000 point barrier on the MSDN forums!

It's much harder to get rep. on MSDN than on stackoverflow.

Enjoy!

Wednesday, January 08, 2014

C# : Cross site scripting and quotes

Busy developing a web site (ASP.NET, C#, Windows Forms, .NET Framework 4) and I got some security gurus to help do some security / penetration testing.

The site has some forms where you enter user details into text boxes. This is stored in a DB. You can search for users and the results are displayed in a grid e.g. first name, last name, email, roles etc.

So if you entered some Javascript into the last name text box e.g.

script Alert ('XSS error'); /script

(insert your own angle brackets!)

this would be written to the DB and when the grid displayed the next tine, you would see the Alert - the dreaded XSS syndrome.

Microsoft has a library to handle this - the somewhat maligned AntiXSS.

This has methods for HTML encoding, CSS encoding, URL encoding, injection etc.

So e.g. you can use:

AntiXssEncoder.HtmlEncode(lastname, true);

If someone types:

 script Alert ('XSS error'); /script

as a last name, this is encoded as:
 
<script>Alert (‘XSS Error’);</script>


which is harmless.

Now that's all well and good but you will note from the above that the single quote "'" is also encoded.

So what happens when you have someone with a name of O'Reilly?

Bad stuff happens - that's what!

What is saved is:

O'Reilly

There are many Google hits around the fact that the library is actually too strict etc. etc.

What I do is after the encoding, is:

lastname.Replace("& # 3 9 ;''", "'");     // Remove the spaces

So it's back to the single quote.

 You could also use something like:

Sanitizer.GetSafeHtmlFragment (lastname);

which removes a few HTML elements like script - so in this case there's just an empty string.

And for injection e.g. LDAP, you can use:

Microsoft.Security.Application.Encoder..LdapFilterEncode("xyz");

Enjoy!




Wednesday, December 18, 2013

ADFS : Integrating with AuthorisationServer

Have been playing around with this and using ADFS as my IDP.

Good article on how to do this - Adding OAuth2 to ADFS (and thus bridging the gap between modern Applications and Enterprise Back ends).

But I battled with getting the admin stuff to work.

When you first configure it, it asks for an admin. name that is written to the SQL CE 4.0 DB.

Put some thought into this because this is an attribute that you have to provide in the form of a claim.

Assume my standard login name is jbloggs. So that's what I entered.

But when I configured ADFS, I mapped DisplayName to Name. But my DisplayName is "Joe" or "Joe Bloggs" or whatever.

So I ended up mapping my sAMAccountName (which is jbloggs) to Name and all was well.

Also, the DB is placed in the AppData folder and the file type is .sdf.

I found the easiest way to examine it was via LinqPad.

"Add Connection" / Next / Provider = CE SQL 4.0 / Browse to sdf file / OK.

Enjoy!

Tuesday, December 10, 2013

Azure : Azure Active Directory and Web API

Two new labels today - moving off on another tangent!

Vittorio wrote an excellent article Secure ASP.NET Web API with Windows Azure AD and Microsoft OWIN Components.

When I tried to do this, ran into two problems.

Firstly, we have a *&&^%^%%$ corporate proxy - I HATE them.

So had to add the following to the test client in the web.config or app.config:
system.net
defaultProxy enabled="true" useDefaultCredentials="true"
proxy bypassonlocal="True" usesystemdefault="True"
defaultProxy
system.net
Insert your own xml start / end format!

Secondly, got the error:

"System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure."

In Vittorio's example, he uses localhost for the web site as did I.

You have to ensure you have no certificate errors when you browse to localhost - you can check that in IE - the certificate box should NOT be red.

If it is, just click it and run the wizard to import it into the "CA Trusted Root" area.

Also, make sure that it has not expired!

Enjoy!



Wednesday, November 27, 2013

Misc : Certificate conversions

On Windows, you have the good, old PFX file which contains both the certificate and private key (and the password for the private key).

But in the Linux world, when you complete the certificate request, you get the information in separate files i.e.

  • cert.crt       (the certificate)
  • cert.key     (the private key)
  • ca.crt         (the CA information)

To convert them into something Windows can use, you need OpenSSL.

You can get a Windows version here: Win32 OpenSSL Installation Project

(Please make a donation if appropriate).

The command you need is:

openssl pkcs12 -export -out cert.pfx -inkey cert.key -in cert.crt -certfile ca.crt

You may get an error:

"unable to write 'random state'"

in which case, set an environment variable:

set RANDFILE=C:\"Directory files are in"\.rnd

Out of interest, if you want to go the other way:

openssl pkcs12 -in cert.pfx -out cert.cer -nodes

Enjoy!

Wednesday, November 06, 2013

ADFS : Changing service communications certificate

This is on Server 2008.

If you've used ADFS for a while, you'll know that the certificates expire, you get new ones and add them and so on.

After a while, the certificate store looks like a mess! Many certificates with the same name.

So you have the bright idea of deleting them all, importing the new one and configuring the new one in ADFS.

BAD move:

When you try and add the new service communications certificate, you get:

Error: AD FS Management
The certificate could not be processed.
Error message: Object reference not set to an instance of an object.

WTF?

This article goes into detail but I still couldn't get it to work.

How to change the ADFS 2.0 service communications certificate after it expires

So you import the new certificate and you've added the new certificate to the IIS https binding.

Mr Google to the rescue and you need to run PowerShell as administrator:

Add-PSSnapin Microsoft.Adfs.PowerShell

Then get the new certificate thumbprint from MMC and use the following:

Set-ADFSCertificate -CertificateType Service-Communications -Thumbprint xxyyzz...

WARNING: PS0001: One or more of the specified certificate(s) has a key length of less than 2048 bits. This may present a security risk.
WARNING: PS0038: This action requires a restart of the AD FS 2.0 Windows Service. If you have deployed a federation server farm, restart the service on every server in the farm.

So restart the service and Hallelujah it all works again!

Enjoy!