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!



Thursday, October 31, 2013

Visual Studio : Version issues

Once upon a time, we had VS 2010 and a tool called FedUtil which could be run many times to change the WIF parameters for different hosts, certificates etc.

Also, FedUtil could be run standalone so you could use it on different boxes when you promoted a build from e.g. Dev to Test.

There was no internal STS so we all used SelfSTS.

Then we had VS 2012, where FedUtil morphed to the "Identity and Access Tool" which added some capability but could no longer be run standalone. The "Identity and Access Tool" could be run many times.

It included an internal STS.

Now we have VS 2013 which has a "Change Authentication" feature invoked when you create a project.

There is no internal STS.

You cannot run it standalone and worse of all you cannot run it after the project has been created.

So what happens when I want to migrate my VS 2012 projects to VS 2013?

This SUCKS massively big time.

Is there anyone at Microsoft that actually uses these tools in the real world. Because if there was they wouldn't introduce such restrictions.

Seriously people, get your stuff together!

If you agree, vote here:

In VS 2013, allow ability to run the "Change Authentication" wizard AFTER project is created

Enjoy!

Monday, October 07, 2013

ADFS : Could not establish trust relationship for the SSL/TLS secure channel

The full 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.

Trying to get the Web Application Proxy on Server 2012 R2 working with the new ADFS.

Mr. Google to the rescue.

You need to export the certificate (the one behind the federation server name) and place it in the "Computer account" (not "My user account") under "Trusted Root Certification Authorities".

And while I'm on the subject:

Every time you try and install the proxy, it creates certificates under Personal called "ADFS ProxyTrust - machine name".

But if the installation fails. the old ones are not deleted.

Then I got the above error message but the thumbprint in the message was from a previous attempt not the latest.

So I uninstalled WAP and then deleted all these certificates- under "Local Computer - Personal - Certificates".

Then I went to the ADFS installation and under the Service tab - "Revoke All Proxies".

Then re-installed WAP.

Then it worked!

Enjoy!

Friday, October 04, 2013

ADFS : Some musings on Server 2012 R2

Having been through the exercise of installing the latest invocation of both ADFS and the Web Application Proxy:

Don't use CNG certificates. And guess what?

The command

New-SelfSignedCertificate 

which is available on Windows 8 and Windows Server 2012 produces (you guessed it) CNG certificates.

So you need to indulge in some time travel to create older version of self-signed certificates.

And the certificate needs SAN's as per the lab.

Massive change in that neither ADFS nor the proxy is based on IIS. Rather I gather it's built on HTTP.SYS.

So how do you now find the SSL binding?

Use:

netsh http show sslcert 

So how do you customise the screens? Even something as simple as branding?

It now uses GMSA instead of service accounts which take time to replicate.

You need to plan to do this:

Add-KdsRootKey 

the day before. There is a hack as per the lab for test environments:

Add-KdsRootKey –EffectiveTime (Get-Date).AddHours(-10)

The WAP is behind the "Remote Access Management" tile.

And once you have published a web application you can't edit it. Seriously?

Also, you need to import the certificate that matches the application URL for it to appear in the drop down box.

Documentation (to be polite) is somewhat lacking. C'mon people!

Enjoy!



Thursday, October 03, 2013

IE : There is a problem with this website's security certificate

You see this all the time with ADFS especially when setting up new Claims Provider trusts.

ADFS won't accept the metadata if the certificate isn't trusted.

Normally, you just click on the "Security Report" icon in the bar at the top of IE, then "View Certificate", then "Install Certificate".

The "Install Certificate" button won't show if you are not running as Administrator.

But in Server 2012, IE 11, I could not get the button to appear.

Mr. Google to the rescue and it turns out you have to add the site to "Trusted Sites", restart IE and then it magically appears.

Enjoy!

Wednesday, October 02, 2013

ADFS : Problem with CNG certificates

Busy having a look at the latest ADFS 2.1 on Windows Server 2012 R2.

This is the one with the Web Application Proxy, MFA etc.

So first off, I need a self-signed certificate.

As per the lab, I need a self-signed certificate with SAN e.g.
  • Subject Name (CN): adfs1.contoso.com
  • Subject Alternative Name (DNS): adfs1.contoso.com
  • Subject Alternative Name (DNS): enterpriseregistration.contoso.com
Hmm - problem.

So what tools are on the box. Oh, frabjous joy - there's a PowerShell command:

New-SelfSignedCertificate 

which is available on Windows 8 and Windows Server 2012.

OK - so try to install ADFS and it complains that the certificate is a CNG (Certificate Next Generation) one which ADFS doesn't support.

WTF? - the new ADFS doesn't support the latest standard? Is this not a security system?

My normal way of generating self-signed certificates is to use SelfSSL7.

But this doesn't run on Server 2012 because it uses .NET 4.5 and SelfSSL7 requires .NET 3.5.

So the options are:
  • Add the .NET 3.5 role to the server
  • Download the source and recompile for .NET 4.5
  • Create on a Windows 7 box and export
  • Use another tool e.g. makecert
But there's another problem:

SelfSSL7 by default does all the IIS SSL binding and this version of ADFS does not use IIS.

So my command was:

selfssl7 /N cn=adfs.domain.com;cn=adfs.domain.com;cn=enterpriseregistration.adfs.domain.com /K 1024 /V 700 /T /X /F c:\xxx\cert.pfx /W password

i.e. just create a pfx file.

Then import the pfx file into the local certificate store - the same one that New-SelfSignedCertificate would have used i.e.

New-SelfSignedCertificate -DnsName www.fabrikam.com, www.contoso.com -CertStoreLocation cert:\LocalMachine\My

Enjoy!






Wednesday, September 04, 2013

C# : Always learn something new

Saw this on Rob Miles blog.

What does ?? mean in C# ?

You can read the full article but the essence is:

"?? provides a convenient way that I can map the null value of a nullable variable onto a specific value

int actualAge = customerAge ?? -1;
 
It saves us having to write code that tests for null and sets a value appropriately. 

The above statement sets the value of actualAge to the value in customerAge unless the value in customerAge is null, in which case it sets it to –1.

if (customerAge == null)
    actualAge = -1;
else    actualAge = customerAge;
 
In other words ?? is a short form of the above test"

Enjoy!
 



ADFS : MSIS7042: The same client browser session has made '6' requests in the last '1' seconds.

Out of the blue, got this problem.

WTF?

So reviewed my changes to date.

I had made a change to fix the ubiquitous problem:

ID3206: A signin response may only redirect within the current web application

If you have played with WIF, you will have seen this particular problem.

The solution is BTW:

Add this to the global.asax

private void Application_BeginRequest(object sender, EventArgs e)
{
      if (String.Compare(Request.Path, Request.ApplicationPath,     StringComparison.InvariantCultureIgnoreCase) == 0 && !(Request.Path.EndsWith("/")))
                Response.Redirect(Request.Path + "/");

}
This seemed to have fixed the bug but then introduced another - the dreaded slippery slope.

After googling around, I found the problem.

In my ADFS RP, I had configured the endpoint without a trailing slash.

Added the missing "/" and all was well.

Enjoy!

Thursday, August 29, 2013

Stackoverflow : onwards and upwards

Moving up the ladder!

Top 3% and all!


Enjoy!

Wednesday, August 28, 2013

C# : String with spaces is not null or empty

Came across an interesting case.

I was checking a text field with

String.IsNullOrEmpty

and I noticed that if you enter spaces, it is neither null or empty!

Mr. Google out of bed bright and early and:

String.IsNullOrEmpty() Check for Space

The solution is the "IsNullOrWhiteSpace(string value)" one.

Enjoy!
 

AAD : SSO between AAD and Salesforce

The write-up is here:

Tutorial: Windows Azure AD integration with Salesforce

but I couldn't get it working.

Luckily, I have some SAML experience so figured out the problem.

I posted before about how important it is to get the NameID stuff right and this was indeed the problem.

When you create the user in Salesforce, you have to make sure that the Salesforce username is exactly the same as the login name you use for your AAD tenant.

And you have to use a valid email name.

The email name and username do not have to match.

So assume I log into my AAD tenant as:

jbloggs@tenant.onmicrosoft.com

My email address is jbloggs@gmail.com.

So I create the Salesforce user with:

email = jbloggs@gmail.com

username = jbloggs@tenant.onmicrosoft.com

Check your email - you will get a "Change Password" email from Salesforce.

Change your password. 

Login to AAD - navigate to the Access Panel - click Salesforce.

What will happen is that AAD will take your logged in name, put it in a NameID SAML assertion called username and pass it to Salesforce.

Salesforce will check that there is a registered user with that username.

There is so A-OK - you are logged in.

I did not have to synchronise any accounts to achieve this.

Enjoy!


Monday, August 12, 2013

ASP.NET : Inline validation controls no longer red

So I had a project that I was busy migrating from .NET 3.5 to .NET 4.5.

Now I use the asp:RequiredFieldValidator controls and suddenly I noticed that the error messages were no longer in red.

I then compared the projects - no obvious .ccs changes or anything like that.

Then I compared the web.config files and noticed that:

pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" validateRequest="false"

had changed to:

pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID" validateRequest="false"

This must have happened during the wizard that migrates the project.

Have a look at:

What's New in ASP.NET 4 and Visual Web Developer

where it mentions that validators no longer render inline color:Red styles.

Changing it back to "3.5" sorted it out.

Isn't red the international error colour anyway?

Enjoy!


Friday, August 09, 2013

WCF : The request for security token could not be satisfied because authentication failed

 

In full:

System.ServiceModel.Security.SecurityNegotiationException The caller was not authenticated by the service. System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.

I see this when the WS call is cross domain on wsHttpBinding.

Quick and dirty is to remove the security (or move to basicHttpBinding).

Not recommended on a Production system but to get over the hump …

On the client side change:

<wsHttpBinding>
<binding name="WSHttpBinding_IService" >
<security mode="None" />
</binding>
</wsHttpBinding>


On the WS side change:


<system.serviceModel>
<services>
<service name=xxx">
<endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary.IService" bindingConfiguration="NoSecurityConfig">
<identity>
<dns value="yyy" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>

<bindings>
<wsHttpBinding>
<binding name="NoSecurityConfig">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>


Essentially, the changes are to add the “security mode = None” and to add the new bindingConfiguration ="NoSecurityConfig" and then specify the binding for it.



Enjoy!






Monday, July 29, 2013

Visual Studio : Could not write lines to file xxx Access to the path yyy is denied

Using Visual Studio 2012, checked a project into TFS and got the above error.

WTF?

Mr. Google to the rescue and the majority view was either:
  • Make the file readable i.e. no readonly
  • Delete the /bin and /obj directories and rebuild
The file was R/W already so went for option 2 and the error disappeared.

All good!

Enjoy!


Wednesday, July 03, 2013

AD : Locked accounts in Active Directory (AD)

This is truly a curved ball.

Once upon a time, there was an attribute in AD called:

  userAccountControl - ADS_UF_LOCKOUT = 16 (d) 10 (h)

However, in later versions of Windows Server (e.g. 2008), this was moved to:

  msDS-User-Account-Control-Computed - UF_LOCKOUT = 16 (d) 10 (h).

BUT there was a slight problem. As the name implies this is a computed attribute i.e. it doesn't actually exist. Rather it is computed on the fly. The implication is that it can't be used in a standard search query.

Hence the curved ball.

Some blogs suggest you can use:

filter = "(&(objectClass=user)(lockoutTime>=0))"  

This works in the sense that it refines a potentially huge list to a much smaller one.

However, it is not sufficient. When a user is locked out and then unlocked, this attribute can be set to zero (as opposed to the previous time that was stored). 

Easy enough, change the filter to:

filter = "(&(objectClass=user)(lockoutTime>0))"  

Dream on - that's not a valid filter query language construct.

So this first list has to be iterated through again to check that the user is actually locked.

Lots of code out there to do this e.g.
UserPrincipal oUserPrincipal = GetUser(sUserName); 
userPrincipal.IsAccountLockedOut();
or if you want to get fancy - refer c# LDAP check user is locked or not
string attribName = "msDS-User-Account-Control-Computed";
user.RefreshCache(new string[] { attribName });
const int UF_LOCKOUT = 0x0010;
int userFlags = (int)user.Properties[attribName].Value;
if ( (userFlags & UF_LOCKOUT) == UF_LOCKOUT)
{
    // if this is the case, the account is locked out
    return true;
}
return false;

To unlock - refer Everything in Active Directory via C#.Net 3.5 (Using System.DirectoryServices.AccountManagement).
UserPrincipal oUserPrincipal = GetUser(sUserName);
oUserPrincipal.UnlockAccount();
oUserPrincipal.Save();
To unlock via ADUC, click the Account tab on the user's Properties and then check the "Unlock Account" check box.

Note: You cannot lock an account either programmatically or through ADUC.

The system will lock the account based on the user's password policy e.g. user will be locked out after x invalid attempts. The policy may state that the user many never be locked out.

Enjoy!

Tuesday, July 02, 2013

Misc : The blog clocks up 100,000 page views

Whoop de do!

100354 pageviews and counting!

Enjoy!

ASP : WTF happened to my asp:Menu in .NET Framework 4.5?

Going through the upgrade exercise I mentioned in my previous post.

All good but my menu is now poked - all bunched up to the left. Still works but looks really munged!

Mr. Google to the rescue!

Menu.RenderingMode Property

The reason is that:

"The value of the RenderingMode property determines how the menu control renders markup for the Menu control.

In ASP.NET 3.5 and earlier versions, the Menu control uses HTML table elements and inline styles to specify the appearance of the menu in a browser. In ASP.NET 4 and later versions, by default the Menu control uses HTML listitem elements and cascading style sheet (CSS) styles."


Enjoy!

WIF : Migrate from WIF 3.5 to WIF 4.5 and VS 2010 to VS 2012


Been going through this exercise lately and thought I would document for others.

Some references:

http://msdn.microsoft.com/en-us/library/jj157091.aspx
http://msdn.microsoft.com/en-us/library/jj157089.aspx
http://msdn.microsoft.com/en-us/library/hh873305.aspx
http://msdn.microsoft.com/en-us/library/hh987037.aspx

Copy project to another directory, make all files R/W and then open with VS 2012. Check migration report.

Remove source control references if applicable.

Under Properties / Application / Target Framework, change to 4.5.

Remove Microsoft.IdentityModel from References

Add System.IdentityModel and System.IdentityModel.Services to references.

Change “using Microsoft.IdentityModel.Claims” to “using System.Security.Claims”

Change IClaimsPrincipal to ClaimsPrincipal

Change IClaimsIdentity to ClaimsIdentity

Change claim.ClaimType to claim.Type. Similarly for ClaimValue etc.

'FederatedPassiveSignInStatus' control has been removed. Remove all references. This includes the
<%@ Register assembly="Microsoft.IdentityModel"
namespace="Microsoft.IdentityModel.Web.Controls" tagprefix="wif" %>
in the aspx pages.

Add STS / FedUtil functionality has been removed. You need to download the “Identity and Access Tool” (available via NuGet).

Running the tool makes “different” changes to the web.config e.g. adds sections for system.identityModel.and a ida:FederationMetadataLocation section.

Comment out all the microsoft.identityModel sections in the web.config.

Update:

<modules runAllManagedModulesForAllRequests="true">
<!-- <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />-->
<!-- <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />-->
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</modules>

Enjoy!

Wednesday, June 26, 2013

SAML : SAML connectivity / toolkit

This is an update to try and categorise this in terms of SAML stacks.

Note that this concerns the SAML protocol not to be confused with SAML tokens or SAML products.

The links in the original article are still valid.

SAML is complicated. Getting the security right is difficult. My advice is not to roll your own.

Note: I personally haven't tried all of these. This is just a list that may be of use.

C#

The WIF Extension for SAML 2.0 is now deprecated and the links have been removed. It is only applicable for .NET 3.5 and is buggy.

There is NO official Microsoft C# client-side SAML protocol stack.

OneLogin's Open-Source SAML Toolkits and Github.

(Libraries for .NET, Python, Ruby, PHP, Java, node and others).

The Kentor stack is now deprecated.
Use Sustainsys - for .Net Core 2 use this version.

Owin.Security.Saml

Using Fedlets in .NET Applications

OIOSAML

SAML2

Safewhere SAML 2 for WIF

Owin.Security.Saml

Java

OpenSAML

Good book on this - Guide to OpenSAML V3.0 and an earlier version Guide to OpenSAML v2.0

Using Fedlets in Java Web Applications 

OneLogin's Open-Source SAML Toolkits

Spring security SAML

OIOSAML

auth10-java

MITREid Connect

PHP

simpleSAMLphp

LightSAML

OneLogin as above.

Ruby

OneLogin as above.

Python

OneLogin as above.

Commercial

Componentspace

Ultimate .NET SAML

Rock Solid Knowledge
This is for .NET Core 2 and is a plugin for Indentityserver 4. 

Identity aaS (as a service)

Auth0 - They do some really neat stuff. Lots of documentation e.g. SAML configuration. See the article at the end of this post

Other

nugetmusthaves for SAML

SAML articles in this blog

Disclaimer

I do not work for any of the above commercial companies.
------------------------------------------------------------------------------------------

There are two previous posts concerning SAML and libraries:

SAML : A SAML stack

WIF : Is there a Java Equivalent?

which are very much focused around the Microsoft / ADFS / WIF scenario.

But there’s tons of stuff out there concerning this so this is just a collection of links – for me as much as for everyone else!

OpenSAML - C++ / Java – open source

Performing a SAML Post with C#

Single Signon with SAML

SAML Single Sign-On (SSO) Component Suite for .NET – commercial

.NET SAML Component - Single Sign-On for C#, VB.NET & ASP.NET – commercial

onelogin SAML Toolkit – C#, ASP.NET, Java, PHP, Python, Ruby

Libraries and toolkits to develop SAML actors and SAML-enabled services

Working with SAML Assertions

Announcing the WIF Extension for SAML 2.0 Protocol Community Technology Preview!

Collection of Useful SAML Tools

authNauthZ  - A Swiss army knife for Graph API / SAML / OAuth

SAML2 for Thinktecture IdentityServer 3 with Kentor.AuthServices

Auth0 - This is essentially Identity aaS. They do some really neat stuff. Lots of documentation e.g. SAML configuration.

(I wrote up an example here using Auth0 -SAML : ASP.NET MVC application talking to SAML IDP.
The service is free until you go into Production and it's not locked down in any way - you have access to all the features).

Enjoy!

Tuesday, June 18, 2013

ADFS : “Problem” with “Token-Groups–Unqualified Names”

 

ADFS has this clever feature where if you select this mapping in the claims rules and map it to Roles, you will get a set of roles claims that contain all the groups for the authenticated user e.g.

http://schemas.microsoft.com/ws/2008/06/identity/claims/role  Role1

That’s well and good when the groups are “flat” i.e. the groups are not memberOf other groups.

If they are, then this mapping will work it’s way up the hierarchy and display ALL the groups.

So if Joe is a memberOf Role1 and if Role1 is a memberOf Role2, then ADFS will construct:

http://schemas.microsoft.com/ws/2008/06/identity/claims/role Role1

http://schemas.microsoft.com/ws/2008/06/identity/claims/role Role2

Now that’s fine if that’s what you want but if Joe has 20 roles and all these roles are at the bottom of a whole pile of other roles you end up with many, many claims and a complete mess!

So what to do if you only want the bottom layer i.e. the actual memberOf.

If you go have a look via ADUC, guess what? memberOf is not displayed as an attribute!

WTF!

To see it as an attribute in the attribute list, you need to click the “Filter” box (bottom right) in “Attribute Editor” and then select “Backlinks”.

OK – so what if we set up a claims rule mapping memberOf to Roles?

So we type memberOf into the LDAP attribute field (it is actually editable) and note that it displays as “Is-Member-Of-DL”.

Problem!

What we get back is the whole CN e.g.

CN=Role1,OU=Sales,OU=company,DC=com

when what we got before was just Role1.

Enter stage left Joji Oshima. He da man!

Refer: AD FS 2.0 Claims Rule Language Part 2.

and have a look at “Problem 1” which is exactly the scenario described above.

Problem solved!

Enjoy!

Friday, June 07, 2013

WIF : Is there a Java Equivalent?


Been asked this question a million times and now I have an answer of sorts.

If by WIF, you mean WS-Federation, then mosey on over to:

Apache CXF Fediz: An Open-Source Web Security Framework
 
This supports:
  • WS-Federation 1.0/1.1/1.2
  • SAML 1.1/2.0 Tokens
  • Custom token support
  • Publish WS-Federation Metadata document
  • Role information encoded as AttributeStatement in SAML 1.1/2.0 tokens
  • Claims information provided by FederationPrincipal interface
However, if by WIF by mean the FAM / SAM / CAM functionality then the jury is still out.

There is no direct Java replacement library for WIF.

Update:

Came across  auth10-java.
  • This library speaks the WS-Federation protocol and SAML 1.1 and 2.0 tokens. It interops fine with Microsoft-related products like ADFS, Windows Azure Active Directory and Windows Identity Foundation. 
Update:

Also  OIOSAML.

Enjoy!

Tuesday, June 04, 2013

SAML : A SAML stack


I answer this question so many times, I’m writing it up as a blog entry.

You have an application – .NET, JAVA whatever.

You want this to be a SP and need to connect to an IDP – ADFS, OpenAM, simpleSAMLPHP …

Look at Announcing the WIF Extension for SAML 2.0 Protocol Community Technology Preview! (.NET).

Warning: This has not been updated in a while.

Warning: This is based on WIF 3.5. It is not compatible with WIF 4.5.

Also the OpenSSO Fedlet – this has components for both .NET and Java.

Or the OpenAM equivalents:

Using Fedlets in Java Web Applications and
Using Fedlets in .NET Applications

Or the Spring Security - SAML Extension (Java).

Or   OIOSAML. (.Net and Java).

Or auth10-java.
  • This library speaks the WS-Federation protocol and SAML 1.1 and 2.0 tokens. It interops fine with Microsoft-related products like ADFS, Windows Azure Active Directory and Windows Identity Foundation.
Or Kentor.AuthServices

  • A SAML2 Service Provider for ASP.NET. Built to mimic the WSFederationAuthenticationModule in .NET 4.5, but using SAML2 instead. The module works with the claims model of .NET 4.5 and uses the present infrastructure for claims translation, session authentication cookies etc.
Or SAML2

  • NuGet package - A .NET implementation of the SAML 2.0 specification for SP integrations. 
  • "Install-Package SAML2" from the Package Manager Console  
Or Safewhere SAML 2 for WIF

  • SAML 2.0 for WIF is a new DLL component that extends the WIF with native support for the SAML 2.0 protocol. (.NET)
Or take your pick from this list:

SAML-based products and services
Enjoy!

Thursday, May 30, 2013

ADFS : Setting up a proxy


If you are planning to set up a proxy in the future, do NOT install ADFS as a single instance, non farm development only instance.

If you do this, you will not be asked for the service account.

When you set up the proxy, it will ask you for this!

Rather install ADFS as a single instance farm – even if you have no intention of ever extending the farm.

WID or SQL – makes no difference.

In this scenario, you are asked for a service account. So you know what to type when the proxy install asks you.

Obviously, you need to set up the service account beforehand – a normal account with no special privileges is fine.

The point being that the install needs to create a SPN for the federation service name and it needs a service account to hold the value!

Enjoy!

Monday, May 27, 2013

ADFS : The remote certificate is invalid according to the validation procedure


So playing around with the proxy and using self-signed certificates and get the above error.

WTF?

So Mr. Google to the rescue and there’s much discussion about disabling the chain revocation checking on the certificate on the ADFS server. This can be done through the PowerShell commands.

But there doesn’t seem to be a command to do this for the proxy.

So pull hair out and then found an entry that suggested that the key was to import the certificate of the ADFS server to the proxy but import it to the Computer Account instead of the “my user” aka “personal” aka “local” account.

Job done!

Enjoy!

Wednesday, May 22, 2013

ADFS : using the WAUTH parameter


In ADFS, you can alter the default authentication chain by changing the order of the local authentication types.

<localAuthenticationTypes>      
    <add name="Integrated" page="auth/integrated/" />
    <add name="Forms" page="FormsSignIn.aspx" />    
      <add name="TlsClient" page="auth/sslclient/" />
      <add name="Basic" page="auth/basic/" />
</localAuthenticationTypes>
 
But what if your WIF application wants to do something different e.g. the ADFS 
above wants Integrated but you want Forms?
 
The trick is to alter the application’s web.config.
<federatedAuthentication>
  <wsFederation passiveRedirectEnabled="true" issuer="https://xxx/adfs/ls/" 
realm="https://xxx/app/" authenticationType="urn:oasis:names:tc:SAML:1.0:am:
password" requireHttps="true" />  <cookieHandler requireSsl="true" />
</federatedAuthentication>
 
The allowable types for authenticationType:
 
Windows integrated authentication:
urn:federation:authentication:windows

User name/password authentication i.e. Forms:
urn:oasis:names:tc:SAML:1.0:am:password

SSL client authentication:
urn:ietf:rfc:2246

As for the WIF claims:

Windows integrated authentication:

http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod =
http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows


User name/password authentication i.e. Forms:

http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod =
http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password


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

Enjoy!

Monday, April 29, 2013

WCF : Different flavours of ADFS


Playing around with the active profile in ADFS – quite a different beast to the passive one!

There are essentially two WCF flavours viz.

1) A simple WCF connection protected by ADFS with hard-coded credentials e.g.

ServiceClient sc = new ServiceClient();
if (sc.ClientCredentials != null)
{
    sc.ClientCredentials.SupportInteractive = false;

    sc.ClientCredentials.UserName.UserName = "user";
    sc.ClientCredentials.UserName.Password = "password";
}

In this case, the claim will always have the same information; the configured attributes for the hard coded user.

2) Using the WCF web service in a an “ActAs” scenario.

There are examples of this in the Training Kit and the WIF SDK (note we are talking WIF 1.0 here). These invariably use the CreateChannelActingAs method.

Dominick has a slightly different approach – refer Requesting Delegation (ActAs) Tokens using WSTrustChannel (as opposed to Configuration Madness).

Here the WCF claim will have the attributes of the logged-in user i.e.

The application is protected by ADFS using the passive profile. The user logins to the application in the normal manner. The application calls a WCF web service using the active profile using ActAs.

This possibly offers another level of security.

Assume the web service is:

DoSomething (string userName).

With the first flavour, you have to pass the user name since the claim is of no use. However, with the second flavour, you can simply call:

DoSomething ()

and get the userName from the claim.

Of course, that does somewhat muddy the water if you want to call the web service from something like Java but that’s another story.

Enjoy!

Friday, April 26, 2013

ADFS : WCF web service

 

Been playing with ADFS and WCF. There’s tons of stuff about the passive scenario but very little useful information about the active one. Actually, that’s not true . There is lots on the active profile – sadly, most of it is rubbish.

I read Dominick’s posts a few times – starting with WIF, ADFS 2 and WCF–Part 1: Overview. There’s six parts. Some of my code comes from there. There’s a link to all the code at the end of Part 2.

This is what I did in VS 2010 / WIF 1.0.

Create a WCF service in WCF – the standard IService1 / Service1.

Add a ViewClaim class:

using System.Runtime.Serialization;

namespace ADFSWcfServiceLibrary
{
[DataContract]
public class ViewClaim
{
[DataMember]
public string ClaimType { get; set; }

[DataMember]
public string Value { get; set; }

[DataMember]
public string Issuer { get; set; }

[DataMember]
public string OriginalIssuer { get; set; }
}
}

The usual contracts:

 [OperationContract]
List<ViewClaim> GetClaims();
public List<ViewClaim> GetClaims()
{
var id = Thread.CurrentPrincipal.Identity as IClaimsIdentity;

return (from c in id.Claims
select new ViewClaim
{
ClaimType = c.ClaimType,
Value = c.Value,
Issuer = c.Issuer,
OriginalIssuer = c.OriginalIssuer
}).ToList();
}


 



Run it up with F5. It starts up the test tool – you’'ll get a null object because there aren’t any claims.


Publish this to IIS 7.5. (IIS needs SSL). Use the file option and stick it somewhere. If you look in the directory where you published it, you’ll see a .svc file. If you navigate to the .svc file via the browser you’ll get the standard:


“You have created a service.


To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:”.

I use IIS 7.5 because Cassini (the internal VS web server) is rubbish with https which ADFS relies on.


Now run FedUtil. Point to the web.config in the directory where you published it and use the .svc address for the website. Use http for the address. Use your ADFS as the existing STS.


At this point, you can’t use the WCF test tool any more. You need to create a client.


What I do now is use something like WinMerge to compare my project with the directory where the project was published.


I copy all the FederationMetadata back and copy the file web.config to the project app.config.


Now I have an updated project.


Add the published web service to ADFS as an RP. You should be able just to point to the metadata using https. Configure some claims.


Now add a command line project to your solution. Make it the Startup Project.


Add the web service as a service reference.

Add something like this to Program.cs

try
{
ServiceClient sc = new ServiceClient();
if (sc.ClientCredentials != null)
{
sc.ClientCredentials.SupportInteractive = false;


sc.ClientCredentials.UserName.UserName = "user";
sc.ClientCredentials.UserName.Password = "password";
}


ViewClaim[] vc = sc.GetClaims();


foreach (var viewClaim in vc)
{
Console.WriteLine(viewClaim.ClaimType = " " + viewClaim.Value);
}
}

catch (Exception ex)
{
Console.WriteLine(ex.Message + " Inner = " + ex.InnerException);
}


Console.ReadKey();


The sc.ClientCredentials.SupportInteractive = false; is to get rid of CardSpace.


Look at the app.config for the command line program. You’ll see a whole lot of commented out services e.g.


<issuedTokenParameters>
    <issuer address=https://xxx/adfs/services/trust/2005/usernamemixed bindingConfiguration=https://xxx/adfs/services/trust/2005/usernamemixed
    binding="wsHttpBinding" />


By default, it’s set up to use services/trust/2005/certificatemixed under the WS2007FederationHttpBinding_IService binding.


Choose the binding you want and overwrite the certificatemixed entry with the one you want.


For the above code, I selected services/trust/2005/usernamemixed.


Run it – you should get the claims for the user you hard coded in sc.ClientCredentials.


Enjoy!

Monday, April 15, 2013

ADFS : SAML configuration parameters

 

Having done this too many times and pulled out too much hair in frustration …

When you are asked to configure SAML access to application xxx owned by company yyy via ADFS v2.0, you need the following information.

If their SAML stack is a well-known product e.g. Ping, OpenAM, Oracle, simpleSAMLPHP … your life is suddenly orders of magnitude easier. You can follow the normal metadata (idp.xml, sp.xml) exchange.

If the words “home brewed” / “custom” / “proprietary” etc. are used, prepare for a load of pain.

The questions:

SAML 1.1 or SAML 2.0?

IdP or SP initiated?

HTTP POST, Redirect or Artefact?

What SAML stack implementation do you use?

Is there an installation document?

If no document, what is …

  • SP entity ID?
  • https SAML endpoint?
  • SAML subject NameID format e.g. UPN, email?
  • What attribute do you expect to use for NameID e.g. UPN, email?
  • What AD attribute is used to populate this?

Do you have the normal SAML metadata exchange protocol file?

Is the SP token required to be encrypted? Certificate?

Are AuthnRequests and Assertions expected to be signed? Certificate?

Single Logout (SLO) required?

SHA 1 or SHA 256?

The above can be configured via the normal ADFS screens.

There are others that require the AD FS 2.0 Cmdlets in Windows PowerShell. These are normally figured out by trial and error. In my experience, asking these types of questions just results in blank looks. You have to “suck it and see” as they say in Kiwiland!

e.g. if ADFS is the RP, then SamlResponseSignature may need to be changed.

This specifies the response signatures that the relying party expects. Valid values are AssertionOnly, MessageAndAssertion, and MessageOnly.

The default is AssertionOnly.

Enjoy.

Tuesday, April 09, 2013

AD : Using a filter for UAC bits and null attributes

 

There’s a lot of functionality in the AD API’s and there are neat API’s to enable / disable users but what if you want to search for them e.g. find all users in an OU that are currently disabled.

You could just search for all the users in an OU and then enumerate through all of them where:

user.Enabled = false;

but that’s a pain.

Enter RFC2254.

Or look here: Search Filter Syntax

What you will find is the matching rule OIDs.

e.g.

1.2.840.113556.1.4.803 = A match is found only if all bits from the attribute match the value. This rule is equivalent to a bitwise AND operator.

UAC is described here: Attributes for AD Users : userAccountControl.

Note that: Const ADS_UF_ACCOUNT_DISABLE = 2.

So now that we have laid the framework, back to the original question.

To search for disabled users, the filter would be:

(userAccountControl:1.2.840.113556.1.4.803:=2)

One of the problems with AD is “null” attributes i.e. attributes that in ADUC display as “not set”.

To search for these e.g. for email, use the filter:

(!(email=*))

* is the AD wildcard so this searches for users who don’t have an email address.

So to search for disabled users who don’t currently have an email address, use:

(&(userAccountControl:1.2.840.113556.1.4.803:=2)(!(email=*)))

This stuff does your head in!

Enjoy!

Wednesday, April 03, 2013

ADFS : ID4175: The issuer of the security token was not recognized by the IssuerNameRegistry


The full error is:

ID4175: The issuer of the security token was not recognized by the IssuerNameRegistry. To accept security tokens from this issuer, configure the IssuerNameRegistry to return a valid name for this issuer.

So there I was happily using my claims-enabled application until one fine autumn morning – WHAM – I get the above error.
WTF?
This error means (to quote Common Windows Identity Foundation WS-Federation Exceptions Explained) that:
“Security tokens are signed by the issuer (the IP-STS). This issuer is validated by the relying party so that the RP can be sure the tokens have been issued from a trusted source. The relying party’s WIF configuration contains an <issuerNameRegistry> element where the settings for the issuer’s signature are stored. This exception means that the configuration contained under the issuer name registry does not match the signature of the security token.”
Then I noticed that my ADFS has certificate rollover enabled and yes – you guessed it – my certificates had rolled over over the weekend.
The section in the web.config looks like:
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.
ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, 
Culture=neutral, PublicKeyToken=31bf3856ad364e35">
        <trustedIssuers>
          <add thumbprint="xxx" name="http://yyy/adfs/services/trust"/>
        </trustedIssuers>
</issuerNameRegistry>

So you need to get the thumbprint of the new ADFS token-signing primary certificate and update the web-config with it.


Enjoy!

Monday, March 25, 2013

WIF : Claims Aware Web Service exception

 

This is with the “Identity and Access Tool” / VS 2012.

When you run the sample and hit Enter, get:

Security negotiation failed because the remote party did not send back a reply in a timely manner. This may be because the underlying transport connection was aborted.

Server stack trace:
   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)

When you click on ClaimsAwareWebService.svc in the Directory Listing, you get:

The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the service type with RequirementsMode setting as 'Allowed' or 'Required'.

So in the web.config, set this to “false”:

serviceHostingEnvironment aspNetCompatibilityEnabled="true"

All good!

Enjoy!

WIF : Identity and Access Tool

 

This happened a while back but there still seems to be confusion.

This only runs on VS 2012.

Also there have been a lot of changes from WIF 1.0 (3.5) to 4.5. The templates, custom STS, FedUtil etc. are no more. Goodbye to the FederatedPassiveSignInControl and FederatedPassiveSignInStatus controls.

Good summary: What's New in Windows Identity Foundation 4.5

Overview: Windows Identity Foundation Tools for Visual Studio 2012 RTM

Details: Windows Identity Foundation in the .NET Framework 4.5 Beta: Tools, Samples, Claims Everywhere

The Identity Training Kit is no more. Examples are spread across separate samples. The full list is in the third link above.

Enjoy!

Friday, March 22, 2013

ADFS: Certificate Sharing Container

 

If you are wondering where this is in AD (and you are not alone in asking that question), it’s to be found under:

Program Data / Microsoft / ADFS

And I believe that this is only used when you enable AutoRollover.

Enjoy!

Misc: .NET 4.5 / Windows Identity Foundation should include SAMLP support

 

Damn fine idea – 100% agree.

We need full SAML support – ala the old WIF 3.5 CTP.

Vote here: .NET 4.5 / Windows Identity Foundation should include SAMLP support.

And yes – I voted.

Enjoy!

Wednesday, March 20, 2013

Rant: If you are already in a hole ..

 

Well – YAC – Yet Another Category!

The actual quote is “If you are already in a hole, stop digging”.

I see this every day. We go to a customer, talk about claims-enabled applications. talk about WIF and ADFS, SAML, SSO etc. and the customer is happy.

Then they ask “Actually we’ve got this open-source gateway product that we use. Can ADFS work with it?”. This gateway product is a “sort-of” AM ala TMG, UAG, OpenAM etc.

The correct response is “Sorry, we can’t be experts in every product in the known universe. You probably need to go back to the vendor. We might be able to help but it’s on a ‘best endeavour’ basis – no guarantees”.

The incorrect response is “OK no problem, we’ll check it out”. The customer interprets this as “OK – now it’s your problem”.

Two months later – one pissed-off customer – the guy who wrote the product is somewhere in Siberia – doesn’t answer emails – and we keep on digging the hole deeper.

Tell the customer up front – we are IDENTITY people NOT network people. If they want to get pissed off, well and good – they can find someone else to sort it out!

Enjoy!

Thursday, March 14, 2013

ADFS : Using the SAML NameID to map IdP / SP claims


Imagine two companies: Fabrikam and Contuso. Fabrikam has a SaaS application in the cloud that Contuso wants to use. Fabrikam supports SAML authentication and is a SP. Contuso uses ADFS as an IP.

So all the pieces are in place and it should just work no problem. Dream on.

There needs to be a “primary key” that links the two companies together for a session.

Assume Contuso has an employee – the ubiquitous Joe Bloggs - and Joe needs access to the application.

So Contuso has to send Fabrikam a table of users – among which is Joe Bloggs. This table can be sent as XML, xls, text or whatever.

Fabrikam imports these users into the Contuso section of their database.

They also have to agree on what attribute of each user is the primary key e.g. sAMAcountName, email address, AD GUID …

Assume they choose email – this is the NameID.

So when Fabrikam get an AuthNResponse from Contuso, they extract the NameID and use that as the key into their table.

There is one further complication. The SAML spec. allows the NameID to be sent in a number of formats e.g. Unspecified, Email, X509 Subject Name…

This is important. If one side expects the email format e.g. joe.bloggs@contuso.com and the other side is expecting X509 Subject Name e.g. CN=joebloggs@contuso.com, OU=Dev,O=Contuso,C=NZ, you can predict that there will be problems.

So they both have to agree. Assume they choose email address.

To configure this in ADFS:

Configure the email address as the normal “Send LDAP Attributes as Claims”.

Then configure a “Transform an Incoming Claim” rule which takes “Incoming Claim Type” of email and maps it to “Outgoing Claim Type” of NameID which has an “Outgoing NameID Format” of email.

Problem solved!

Enjoy!

Friday, February 22, 2013

ADFS : Getting the domain name as a claim

 

There are a number of ways of doing this.

You can get the domain name via ADFS : Sending groups as claims.

Also there was a thread on the forum that I contributed to viz. Custom Claim Rules - How to write domain name into outgoing claim?.

As I said, you could map msDS-PrincipalName to http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname and then use some regex to split out the domain name.

But further down:

“You don't need to use any mapping/edit LDAP rules and stuff. The windowsaccountname claim is there by default after installing adfs.

Just check it for yourself:

-Open the ADFS 2 console

-Open Trust Relationships

-Open Claims Provider Trusts

-Right mouse click on the AD trust and click "Edit claim rules"

-Note the first rule: Pass through all Windows account name claims.

You can just use the "Pass through or filter an incoming claim option" in the relying party claims configuration and select the windows account name or use a custom transform rule to transform it to the desired outgoing claim.”

Very neat!

Enjoy!

Tuesday, February 05, 2013

ADFS : New RP / SP metadata for expired certificate

 

Common pattern – you set up a link with a WS-Fed RP or a SAML SP and for whatever reason they use a certificate and it’s expired.

That site has a load of claims rules and it’s a real pain to delete the site, re-import the metadata, type in all the claims rules again etc.

But wait – help is at hand.

Instead of sending you all the metadata, just ask them to send you the certificate as a .cer text file. That’s the format that look like:

-----BEGIN CERTIFICATE-----

<snip>

-----END CERTIFICATE-----

In ADFS, double-click on the RP in the “Relying Party Trust”.

Then click on the Signature tab.

Then click on the “Add” key, browse to the .cer file, select it etc. and viola – you have updated the certificate without having to do the whole nine yards.

Enjoy!

Thursday, January 31, 2013

Friday, January 18, 2013

stackoverflow : The forum double


In cricket, we have the concept of the “all-rounder’s double” for cricketers who have scored 1000 runs and taken 100 wickets or whatever.

So I set myself the “forum double” of 10,000 points on stackoverflow and 1,000 points on the Microsoft .NET Framework Forums. It’s a LOT harder to get points on the Microsoft forum – trust me.

This is completely arbitrary but what the hell.

The stackoverflow goal was achieved a while back (refer previous posts) but I’ve just achieved the Microsoft one.

ScreenShot090

Enjoy!

ADFS : objectGUID as a claim


You may have a business requirement to pass some unique key to the application that is not readily identifiable or editable. There are two possibilities in AD viz. objectSID and objectGUID.

As per SID vs. GUID, objectGUID is the better choice because:

“globally unique identifier (GUID), which is a 128-bit value is unique not only in the enterprise but also across the world”   and
“the values of other object properties can change, but the object-GUID never changes. When an object is assigned a GUID, it keeps that value for life”. 

So you configure the claim in the normal LDAP attribute manner and when you look at the claims, you see:

http://schemas.company.com/identity/claims/objectguid kzGVAByOYki4z7CdR2yecA==
WTF – that ain’t no GUID? The two equal signs at the end would seem to indicate Base64?

Mr. Google to the rescue and viola Issuing objectGUID as an ADFS Claim.

So lets test it out. Couldn’t be bothered to create a VS project just for this so the inestimable LINQPad to the rescue.

ScreenShot089

And the GUID at the bottom is indeed what is displayed in AD.

Enjoy!

Monday, January 07, 2013

ADFS : Forum about to be retired

 

Refer : This Forum Is to Be Retired.

After a number of posts from people much more knowledgeable and much more influential than me happy to see that the decision was reversed.

Nice one Microsoft!

But I do content myself with the fact that I had a small part to play in all of this!

Enjoy!