Friday, December 19, 2014

ADFS : ADFS 3.0 and OpenID Connect / OAuth 2

This is for Server 2012 R2 and the documentation (to be polite) is somewhat lacking!

Came across a really neat tool for testing:

authnauthz

Also, Vittorio blogged some useful information:

Securing a Web API with Windows Server 2012 R2 ADFS and Katana

So let's put the pieces together.

In ADFS, create a RP as per Vittorio's instructions.

There's no certificate and no endpoints because you don't pick either SAML or WS-Fed.

Unlike my usual RP stuff, the identifier is not a URI.

I made the name and identifier simply "OAuth Test".

Then again following Vittorio,

Add-AdfsClient -Name "OAuth Test" -ClientId "112e0117-ef3d-44c4-a367-5b4bef313d8f" -RedirectUri "https://www.authnauthz.com/oauth/inboundauthenticationresponse" -Description "OAuth client"
The ClientID and RedirectURL are from the test tool.

So off to the test tool.

Under OAuth click "OIDC Authentication Request".

The authorisation endpoint is:

https://your adfs/adfs/oauth2/authorize

Response type: Ensure only code is ticked.

ADFS doesn't support anything else.

Set Resource to "OAuth Test"

Remove all Scope.

ADFS doesn't support any.

Click "Submit".

Off to ADFS, authenticate as per usual and you'll be be redirected to the Response page in the tool with an authorisation code.

Enjoy!




Friday, December 05, 2014

ADFS : problems with Issuance Authorization Rules

These rules are useful if you want to allow or deny access to an application based on whether the authenticated user has a particular claim or not.

So I had a situation where there was a workflow involved and a user could not have access until they had been validated by an administrator.

So I created a claim called:

"http://company.com/claims/Validated"

(Remember, these are URI not URL!).

Then in the Issuance Transform Rules tab, I had the normal LDAP rule to create the claim from an AD attribute and in the  Issuance Authorization Rules tab I had a rule that said that if that claim had a value of "True" than allow access. I deleted the default "Allow access to anyone" rule.

Problem was - it didn't work?

Had a chat with Mr. Google (and it was a long chat!) and eventually figured out that each tab stands on its own i.e. there is no cross-pollination between them. The fact that you have a rule in one tab means nothing in another.

You have to repeat the rules in each tab.

Then all was sweetness and light!

Enjoy!

Tuesday, December 02, 2014

IIS : You can ping the box but can't connect to IIS

Had the problem recently.

Laptop all running smoothly - could ping it no problem and connect to it via \\name.

But no way could I http to a website on the laptop.

Did the "ipconfig /flushdns" dance - no joy.

Double-checked all the IIS settings.

Had a chat with Mr. Google and found a suggestion to:

telnet "IP address" 80

This tests if port 80 is open.

No joy - aha - so it's not IIS per se - it's the TCP/IP traffic on port 80.

Run up Windows Firewall. Yup - HTTP traffic on WWW was disabled for port 80. Allowed that - bingo - all A-OK.

Enjoy!

Monday, November 17, 2014

ADFS : Using an AD primary key

There's a common use case where you are using some external system e.g. Facebook to authenticate and ADFS is in the pipeline as a R-STS.

Facebook only returns a GUID which doesn't mean a lot to AD so you have a registration flow where you ask the user for their details e.g. name, email address .. and then map the GUID to this.

So the next time the user logs in you have the GUID but need to use this as a "primary key" to get the rest of the details from AD.

Assume you have placed the Facebook GUID in a claim type called:

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/guid

and it's stored in AD in extensionAttribute1.

So you have a normal LDAP claims rule that maps:

extensionAttribute1 -->  http://schemas.xmlsoap.org/ws/2005/05/identity/claims/guid

Then you need a custom ADFS claim rule to do the extraction based on the mapping:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/guid"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone"), query = "(&(extensionAttribute1={0})(objectClass=user));givenName,sn,mail,mobile;domain\user", param = c.Value);

So the rule searches AD for the user whose extensionAttribute1 value matches "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/guid" and then returns:

"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone"

as four separate claims.

Enjoy!

AD : Information about the domain could not be retrieved (1355)

Setting up a new system with an AD in a DC in another domain that is "sandpitted" and got this error.

"Information about the domain could not be retrieved (1355)".

Can ping the DC but the IP / Name is in my host file - it's not on the DNS.

Lots of stuff on the Internet - mainly red herrings.

The problem was the DNS "hole" - adding this DC as my alternate DNS on my Windows 7 box fixed the problem.

Update

Turns out this is not sufficient. Still get this &^%&^% problem.

 Start / Control Panel / Network and Internet / Network and Sharing Centre

On LHS at top / Change Adapter Settings

Right click / Disable

You will lose your network connection!!!

Right click / Enable

All will be well until you reset your PC and then you will have the joy of doing it all again.

Use at own risk but works for me.


Enjoy!

Wednesday, November 12, 2014

stackoverflow: Writing the perfect question

I've blogged on this before but it bears repeating.

cf Jon Skeet: Writing the perfect question.

There was a question on SO that's a perfect example.

"How do I achieve SSO with site a, site b, WIF and SAML and STS"?

Is site a /b .NET / Java / ...?

What flavour STS?

WIF and SAML are mutually incompatible, Explain.

Are site a / b in different domains? With different identity repositories? If so, what repositories are these? AD or ...?

And so on.

In my experience, the quality of the answer correlates with the quality of the question.

Yeah - I get that people are leaving out important details because they don't really understand the environment.

If so, Google other questions. What details do they supply?

If you want to be noticed in the vast list of SO questions, you have to put some effort in.

Make me want to help you by answering!

Enjoy!
 



IdentityServer: two different WS-Fed endpoints

So I've been using thinktecture's IdentityServer for a project.

First off - it's a damn good product - but then you have two top class MVP's working on it!

I'm using V2.

I'm using it in two modes:

As an IDP against the SQL Server DB
As a R-STS - effectively a broker that just passes on the traffic.

Normally these are the same endpoint e.g. ADFS.

But I was battling until I realised that there are actually TWO WS-Fed endpoints.

My bad - it's obvious when you see the metadata list.

So /issue/wsfed works for the IDP and /issue/hrd works for the R-STS. As the name implies, this brings up the HRD screen.

If you look at the two controllers, the code (as you would expect) is pretty similar and they both share the same WSFederationResult.

Enjoy!

Thursday, November 06, 2014

Windows Server: Where's the drive mapping?

Needed to map a drive on Server 2012 R2 to load some media so:

Start - right click "This PC" - check "Map network drive"

Than map to G: e.g.

Into command prompt with run as administrator set - type "G:" - no such drive - WTF? - I can see the mapping in File Explorer!

Turns out you have to do an extra step i.e.

net use g: \\"mapping path" password /user:domain\user /p:no

where:
g: = drive to map
mapping path = path to media
password = your password
/user:domain\user = your domain and user
/p:no = don't persist mapping across logins

Job done.

I suspect this will work on Windows 8 as well.

Enjoy!

Wednesday, October 01, 2014

ADFS : ADFS 3.0 - no web.config

I've blogged before about the changes in ADFS 3.0 on Server 2012 R2.

No IIS so no web.config.

Hang on - what about things like:

<context hidden="true" />
<error page="Error.aspx" />
<acceptedFederationProtocols saml="true" wsFederation="true" />
<homeRealmDiscovery page="HomeRealmDiscovery.aspx" />
<persistIdentityProviderInformation enabled="true" lifetimeInDays="30" /> 

They are no longer there.

The trick is to use PowerShell: (Thanks @paullem!)

Set-AdfsWebConfig

e.g.

Set-AdfsWebConfig -ContextCookieEnabled $True -HRDCookieEnabled $True -HRDCookieLifetime 30

Enjoy!

Wednesday, September 24, 2014

Misc : Popular posts

There is a little widget that's supposed to do this but here are the actual statistics.


Notice the number of ADFS hits!

Enjoy!

Misc : GitHub for Windows - Clone in Desktop

GitHub for Windows is a neat tool but suffers from a severe lack of documentation.

I find a project I like, click "Clone in Desktop" on the RHS and it takes me to a screen saying "Download GitHub for Windows" even though I have the damn thing already installed.

So ^^%$$% frustrating.

Mr. Google to the rescue and after a number of false starts (Google sucks more and more at delivering useful search results) I discovered that you need to log-in first on the GitHub site.

Then all is OK.

Going by the number of hits I found on this, 99% of this would be avoided if GitHub put a notice to that effect on the page e.g.

"You must first Login".

Enjoy!

Tuesday, September 23, 2014

ADFS : The joys of hidden context

Playing around with ADFS 3.0 on Server 2012 R2 and found yet another difference with ADFS 2.x.

Imagine you have a number of .NET applications going via ADFS as a RP-STS going to another IP-STS.

Now on the IP-STS you want to know which RP the authentication request is coming from.

All the ADFS requests are coming through one channel so parameters like "Referer: " are useless.

In your RP web.config you can add a parameter like wreply or wtrealm as per wsFederation.

You'll see these in the URL going to ADFS in the &wctx section. But there's nothing going to the IP-STS. ADFS "removes" them. Instead there is a &wctx which is a GUID.

And there is a cookie on the way which looks like:

MSISContextc1da81dd-46b6-4cee-b051-9c0e7a298527=xxxyyy==

where xxxyyy is Base64 encoded.

In ADFS 2.0, there was an entry in the web.config which told ADFS not to encode this information in a cookie but to send it as part of the query string - which makes for a lll-oon-nnn-ggg query string!

This entry was:

context hidden="true"
ADFS
But in ADFS 3.0 there is no actual web.config, You have to look in:

C:\Windows\ADFS

and there's a file called:

Microsoft.IdentityServer.Servicehost.exe.config

but it has no such entry.

The trick is to use PowerShell:

 Set-AdfsWebConfig -ContextCookieEnabled $False

Enjoy!

Friday, August 08, 2014

ADFS : Certificate details in the metadata

Common problem - you get sent some metadata that contains certificate info. and then get an error when you try and import it.

Would be really useful to see the actual certificate, right?

Good news is that help is at hand.

In the metadata file, you'll see something like:

<KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>




Then there's the actual certificate info. which is in Base64.

Copy it - the stuff between the open and closing ds:X509Certificate tag.

Now paste that into an editor - Notepad++ is my poison of choice.

Then save that as a .cer file.

Now double-click on the file in Explorer.

Job done!

Enjoy!

Wednesday, July 23, 2014

stackoverflow : 500 answers

Finally hit the mark.

If you calculate that I try to answer one question every day and 5 weekdays per week, then:

500 / 5 = 100 weeks ~ 2 years to get here!

Actually, it's taken almost 6 years.

Can do better!

Enjoy!

Monday, July 21, 2014

SAML : I want to test my code

This question pops up frequently on the forums.

"I have written my own custom IDP / SP. How can I test it against some instance that's publicly available?"

There are a range of commercial products e.g. Tivoli, Oracle, Ping Identity. OpenAM which all deliver this functionality but they are complex to set up and are most certainly not free.

If you work in the Microsoft world and have a "spare" Windows server that's domain joined you can use ADFS. This runs on 2008 R2, 2012 and 2012 R2 and supports both IDP and SP mode.

Open source:

* Shibboleth 
*    and also Testshib
* simpleSAMLphp

Both these support IDP and SP mode.

Others:

SSOCircle - IDP only
Kentor - IDP only
Feide OpenIDP - IDP only
* Salesforce developer - (IDP / SP)

Beware: These are often simplified and some security checks have been removed so the fact that your code works in these environments does not ensure that they will work in the real world.

There are also some commercial / open source implementations for SAML stacks. These often have test IDP and SP that you can run up for basic testing.

ComponentSpace is one example.
onelogin SAML Toolkits - open source

There are others.

Enjoy!

Friday, July 18, 2014

ADFS : ADFS and SAML AuthnContext

This article gives an good overview of the subject:

Authentication Handler Overview

You'll see that normally ADFS will set the AuthnContext to something like "urn:oasis:names:tc:SAML:1.0:am:password" for FBA.

So what happens if you have ADFS as a SP and the IDP demands something else?

If you have a ASP.NET application as the RP, you're in luck. All you have to do is set the wauth parameter as per this article:

Windows Identity Foundation (WIF): How to Utilize the WS-Federation WAUTH Parameter to Specify an Authentication Type

I normally do this in the web.config.

It seems counter-intuitive. wauth is a WS-Fed protocol element not a SAML one but ADFS obviously has the intelligence to pass this through to the SAML IDP in the AuthnContext.

What happens if your RP is SharePoint. Sadly, in this case you are fresh out of options. There are many references to this on the web but nobody appears to have a solution.

You pretty much have to add a proxy to add this element or speak nicely to your IDP provider!

Essentially you have to deconstruct the AuthnRequest, add the AuthnContext stuff and then put it all back together. That's basically just vanilla XML manipulation. However, if the agreement is that the AuthnRequest has to be signed, it's a whole new ballgame. You now have to get your hands on the private key of the SP signing certificate and read the SAML specifications to see which part of the AuthnRequest needs to be the signing input.

If you have certificate rollover set in ADFS, you again are screwed, The signing certificate is not in the certificate store. It's some weird combination of a certificate container in AD, a blob in one of the attributes and a link to the ADFS configuration database.

In this case, turn rollover off, generate your own certificates, place them in the certificate store in the usual manner and you are good to go. Remember to give the application account access to the private key. If that's all Greek, refer:

AD FS 2.0: How to Replace the SSL, Service Communications, Token-Signing, and Token-Decrypting Certificates

under the "Manage private keys" section.

Enjoy!

Wednesday, July 09, 2014

ADFS : Claims rules and regex

I answer a lot of claims rules questions over on the forum:


and a lot of them concern regex.


One of the recent ones concerned:
"This works fine. I want to filter groups that are included in outgoing claim to just groups which start with string "SG". So I wrote custom ADFS rule:

c:[Type == "http://schemas.xmlsoap.org/claims/Group", Value =~
"(?i) ^SG*"]
=> issue(claim = c);"

There's a number of tools to check the regex. I tend to use Expresso.

But then I came across an article which showed an easy way to check this in PowerShell.

PS C:\> "SG1234" -match '(?i)^SG*'
True
PS C:\> "abcSG1234" -match '(?i)^SG*'
False
PS C:\> "SG1234" -match '(?i)^SG.'
True
PS C:\> "SG" -match '(?i)^SG.'
False
PS C:\> "SG" -match '(?i)^SG'
True


 ... and you can see some of the other strings I played around with.

Neat!

Enjoy!

Friday, July 04, 2014

Monday, June 30, 2014

ADFS : VS 2013 and FedUtil

In VS 2013, there was a wizard called FedUtil which handled the "binding" between your WIF project and ADFS, sorted out the web.config configuration etc.

In VS 2012, this wizard was called the "Identity and Access Tool"

In VS 2013, there was - oh that's right - nothing!

But, fear not, there is a way.

Using VS 2013 Update 2:

  • Create an ASP.NET Web Application
  • Click "Change Authentication"
  • Select the "Organisational Accounts" radio button
  • In the "Cloud - Single Organisation" drop down - select "On-Premises"
  • Under "On-Premises Authority", enter the ADFS Metadata URL
  • Under "App ID URI", type the identifier or leave blank for default
  • Click "OK"
  • Back on the "New ASP.NET Project" screen, Authentication should say "Organisational Auth (On-Premises)"
  • Click OK
  • Done

When the project is created, you'll see the web.config has been updated.

Enjoy!


Monday, June 23, 2014

Stackoverflow : 15,000 rep

Well, taken a while but just crossed that boundary!

So I can now:

"protect questions

Privilege type: Moderation privilege
Awarded at: 15,000 reputation"

Only one more privilege to get:

"trusted user
Privilege type: Milestone privilege
Awarded at: 20,000 reputation"

So just a small matter of another 5,000!

Why do I do it? - basically:

  • I like helping people
  • I try and evangelise Identity - and this is a good way to do it
  • I learn something every time I research an answer

Most of the time, I pretty much know the answer but it's that quest for the "perfect" answer that leads to research which leads to me better understanding something.

Also, half the time when I try and explain something I realise I don't understand it as well as I thought I did or as well as I should!

See An Ode to Server Fault for a similar viewpoint.

Enjoy!


Thursday, May 29, 2014

ADFS : Customising the screen for ADFS 2012 R2 or ADFS 3.0 or ADFS 2.2

Update:

More comprehensive write-up here.

Apologies for the title but there doesn't seem to be a standard for what the R2 version of ADFS is called so I included them all to ease the Google / Bing / Duck Duck Go search

If there's one question that has become flavour of the month lately this is it. There are many questions around customising the logon / login / sign on pages.

Some of them refer to customising the pages for Multi-Factor Authentication (MFA). Just remember that you can now do this with a Microsoft solution. Refer: Azure Multi-Factor Authentication. Note that this doesn't have to be cloud based. There is an on-premise variation.

In ADFS 2.0, the functionality was implemented as a web site running on IIS so you could customise to your heart's content changing the .aspx and the .cs pages.

My guess is that some people who didn't really understand the implications of what they were doing customised the pages in sub-standard ways and things went wrong and Microsoft copped the blame for pushing a crap product.

Remember - security in a web application is hard - writing a security application is even harder,

So in ADFS 3.0 this was all locked down. The biggest change was that it no longer uses IIS.

Refer: First Impressions – AD FS and Windows Server 2012 R2 – Part I

There are some PowerShell commands  you can use to customise the screens

Refer: Customizing the AD FS Sign-in Pages

and Advanced Customization of AD FS Sign-in Pages.

There are some good suggestions here:

adfs 2012 R2 forms authentication default login domain

Beware: one of the suggestions here is to modify the .dll. I would strongly suggest that you don't go down this particular rabbit hole!

And a good write up here:

Handling Expired Passwords in AD FS 2012 R2

Enjoy!

Wednesday, May 28, 2014

Visual Studio : Extending the user profile for organisational accounts in Azure

When you use VS 2013 and choose the web application option and then change the authentication options to use organisational accounts, you get a lot of template code which shows you some of the attributes in the user profile derived from Azure Active Directory (AAD).

You can see this if you click on the name of the logged-in user once the application is running and you have authenticated.

What if you want to extend this?

The first step is to find out what the attribute is called?

The easiest way to do this is to use the Graph Explorer.

Click "Use Demo Company" then "Get" then click on:

"https://graph.windows.net/GraphDir1.OnMicrosoft.com/users".

You'll get a list of the AAD schema attributes e.g if you want the user department, you'll see the name is "department".

In the VS project under "Models / HomeViewModels.cs" add another line e.g.

public string Department { get; set; }

Under "Views / Home / UserProfile.cshtml" add another line e.g.

<td>Department</td>
<td>@Model.department</td>
This uses Razor syntax - you may have something different but you get the general idea.

The key to this is under "Controllers / HomeController.cs" where:

UserProfile profile = JsonConvert.DeserializeObject(responseString);
 leverages the power of the JSON library to serialize the attributes you have defined.

Job done.

Enjoy!

Friday, May 23, 2014

Security : Secret Q & A

Came across an interesting idea for the answers to those ubiquitous secret Q & A they use for authentication.

If you see someone lives in NZ and the question is:

Where where you born?

a hacker could answer "Auckland" / Wellington" / "Christchurch" / "Dunedin" and that would cover about 80% of the possibilities since e.g. over 25% of the people in NZ live in Auckland.

So the suggestion is to use a random phrase to answer everything.

e.g.

"Where were you born"?  = Puddleduck
"Mother's maiden name"? = Puddleduck

and so on.

Enjoy!


Tuesday, May 06, 2014

Azure : Deploying a Java web site to Azure

Well, who would ever think that the words "Azure" and "Java" would be used in the same sentence?

I'm not talking about the Azure VM here; rather the Azure web site option.

As Mrs. Beaton would say "First catch your rabbit". For Java, this becomes "First catch your .war file".

You can create a simple Java web site in either Eclipse or NetBeans - whatever floats your boat.

Work through the following documentation:

Get started with Azure web sites and Java

Adding an application to your Java web site on Azure

I used the "Create a Java web site using the Azure configuration UI" option.

OK, but when you display the web site URL, you get the "This Java based application has been successfully created". So where's my index.jsp?

From the dashboard of the Azure web site, you'll see the FTP address. I use FileZilla.

Before you can use this, you have to set the credentials. There's a link under "Quick Glance" called "Reset your deployment credentials". So set them.

Assume your web site is called MyJavaWebSite.

So to get FileZilla to work, you use the FTP URL from the dashboard page, your user name is:

MyJavaWebSite\username

and the password is whatever you chose.

On the LHS menu, navigate to your war file. On the RHS, navigate to:

/site/wwwroot/webapps

Copy the war file over.

Now navigate to the actual Azure web site URL. Still shows the canned screen.

So append  /MyJavaWebSite/index.jsp to the URL.

Bingo.

Enjoy!

Wednesday, April 30, 2014

Stackoverflow : Neat set of badges


Seems somewhat symmetric ...

100 bronze badges - achievement unlocked :-)

Enjoy!

Azure : Web site FTP credentials

In an Azure web site, in the portal under the dashboard on the RHS, you'll see a whole link of links e.g. the link to the site, ftp links, log links etc.

To access these, you need credentials which you can set further up that page on the RHS i.e. "Reset your deployment credentials".

So you pick a name like "myftpusername" and a password.

Then you use something like FileZilla to FTP to the site using the FTP link, you type in the credentials and get "Access Denied"! WTF?

The reason is that you have to add the actual site to the user name. So if the site name is "AnAzureWebSite", then the user name needs to be:

AnAzureWebSite\myftpusername

Enjoy!


Wednesday, April 16, 2014

Misc : Zooming the ZoomIt window

ZoomIt is a fantastic tool for presentations. You'll find it at:

ZoomIt

But I've always battled to get it to display exactly where I want and tracking around the zoomed screen is a nightmare.

Then I figured out that before you hit "Ctrl / 1" to zoom, put the cursor at the middle of the section you want to zoom.

Then zoom.

You can make minor adjustments by moving the mouse, use the trackwheel to zoom in / out, click the left mouse button to "stabilise" and then you are in the "Ctrl / 2" window by default so "Ctrl / Shift" will draw an arrow etc.

And it would be remiss of me not to point out that you can do this in Windows via the built-in commands. In a browser, type "Windows key" and then "+" to zoom out and then  "Windows key" and then "-" to zoom back in. This is in fact the Magnifier tool.

Enjoy!

ADFS : Getting certificate data from metadata

A number of times I've needed to get information about the certificate e.g. to update the WIF thumbprint in the web.config and I've battled to extract this out of the metadata.

For ADFS, you'll find it at:

https://someserver/FederationMetadata/2007-06/FederationMetadata.xml

For Azure Active Directory, you'll find it at:

  • Click on "Active Directory" in the menu on the LHS of the Azure Portal.
  • Click on your tenant name.
  • Click on the "Applications" tab at the top.
  • Click on "View Endpoints" at the bottom.
  • Then navigate to the "Federation Metadata Document" link.


Then I found an easy way to do this based on a post I read.

Open the metadata file in Notepad++ or whatever your particular flavour is and then search for the "X509Certificate" tag.

Copy all the information between that and the closing tag. It's base64 encoded so it will normally end with an "=" sign.

Copy / paste this into a new Notepad++ window. Remove all trailing spaces.

Save the file somewhere with a ".cer" suffix.

Then double-click on the file.

Viola - it opens up the certificate window and you can grab whatever you want.

The thumbprint is found under the "Details" tab - scroll down to the bottom.

Enjoy!

Tuesday, April 01, 2014

Visual Studio : Unable to locate NuGet.exe

Actual message is:

Error - Unable to locate 'C:\.....\.nuget\NuGet.exe'   

You sometimes get this when building a project that you cloned from GitHub.

Under .nuget/nuget.Targets in your project, change:


<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false ...
 
to 
 
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true ...

Enjoy!

Monday, March 24, 2014

Windows : Ctrl - Alt - Del on a VM

If you use Remote Desktop a lot and you get a message about your password needing to change, you can't use:

Ctrl - Alt - Del

because that will change the password on your actual PC - not the box you are RDC'ing to.

All the documentation states:

Ctrl - Alt - End

but sometimes that simply doesn't work.

In such cases, in the RDC window, try Start - Run - OSK.

This pops up the On Screen Keyboard.

Than hold down Ctrl and Alt on your actual keyboard and then click Delete on the OSK.

Job done!

Enjoy!



Friday, March 07, 2014

ADFS : Non domain-joined proxy

All our proxies are domain-joined albeit in a different zone.

Recently, I was involved with a client whose proxy was non-domain joined i.e. a workgroup.

When installing the proxy, you need to enter the credentials of the ADFS service account.

Battled to get this to work and then I remembered that this was not domain-joined and consequently, you needed to enter the sAMAccountName in the form:

domain\user
where the domain is the one that ADFS is installed in.

That did the trick.

Enjoy!

Monday, March 03, 2014

OWIN : WS Federation support

Vittorio blogged on this:

Using Claims in your Web App is Easier with the new OWIN Security Components

There's a good reference to OWIN in the above.

WS-Federation in Microsoft OWIN Components–a quick start

But what the article doesn't show is how to display the claims.

Dominick blogged on this:

Test driving the WS-Federation Authentication Middleware for Katana

Horrible hack below - yeah I know! - I put it in the About page in the HomeController ...

public ActionResult About()
{
     ViewBag.Message = "Your application description page.";

     var ctx = Request.GetOwinContext();

     var user = ctx.Authentication.User;
     var response = ctx.Response;

     response.ContentType = "text/html";

     if (user.Identity.IsAuthenticated)
    {
         ... code as above
    }

Enjoy!

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:
 
&lt;script&gt;Alert (&lsquo;XSS Error&rsquo;);&lt;/script&gt;


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&#39;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!