Ideas and thoughts about Microsoft Identity, C# development, cabbages and kings and random flotsam on the incoming tide
Wednesday, June 26, 2013
SAML : SAML connectivity / toolkit
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
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.
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.
- 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.
- NuGet package - A .NET implementation of the SAML 2.0 specification for SP integrations.
- "Install-Package SAML2" from the Package Manager Console
- SAML 2.0 for WIF is a new DLL component that extends the WIF with native support for the SAML 2.0 protocol. (.NET)
SAML-based products and services
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:
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!