Wednesday, February 03, 2016

AAD : Some protocol conversion

If you've ever looked at Auth0, you'll know that it's basically a circle that handles all the protocols and conversions and all applications and IDP's have one connection to the circle. Anyone can connect to anything.

You can come in with OpenID Connect and a JWT token and exit with SAMLp and a SAML token.

The same kind of thing happens with Azure AD where you have a federated tenant using ADFS for the authentication.

The user accesses a .NET application that uses the OWIN OpenID Connect stack to connect to AAD.

Something like:


If you are wondering about the "domain_hint" see here: Using Azure AD to land users on their custom login page from within your app

AAD sees that this is a federated tenant and hands off to ADFS. The default for the Microsoft stack is WS-Fed.

Something like:

GET https://my-adfs/adfs/ls/?username=&wa=wsignin1.0&wtrealm=urn%3acompany

So AAD has done a protocol conversion from OpenID Connect / OAuth (oauth2/authorize) to  WS-Fed (wa=wsignin1.0).


Friday, January 29, 2016


ADFS v3.0 - Server 2012 R2.

Been doing a PoC with client IDP Initiated via ADFS to a SAML ASP.NET client built on the ComponentSpace SAML stack.

Getting the login to work was somewhat trivial, getting the logout to work was somewhat harder!

The first ADFS error I got was:

MSIS0040: Received LogoutRequest element that is not NameID

Looking at the actual request, I noticed NameID was missing. This was because it wasn't one of the assertions in the login.

So I added a Transform in the RP claims rules to transform email to NameID.

Still got the error and I noticed that the outgoing NameID format was different i.e. email vs. unspecified

Fixed that in the claims rule.

I then got:

The verification of the SAML message signature failed.
Message issuer: https://roryb-lt001/MvcExampleServiceProvider
Exception details:
MSIS7074: SAML authentication request for the WebSSO profile must specify an issuer with no NameQualifier, SPNameQualifier or SPProvidedId properties. 

I have no idea what the bottom part of the error means but the problem was that ComponentSpace wasn't signing the logout.

So I added:


to the saml.config.

(Note that you need a logout service URL as well).

So you need:

  • A NameID
  • The NameID format in the Logout must match that in the Login
  • The Logout must be signed

The signing could also be altered by using one of the ADFS PowerShell cmdlets.

The working logout looks like:

<samlp:LogoutRequest ID="_48141811-d3ab-4d1c-b073-9d8b240489ec"
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://xxx/adfs/services/trust</Issuer>
    <ds:Signature xmlns:ds="">
            <ds:CanonicalizationMethod Algorithm="" />
            <ds:SignatureMethod Algorithm="" />
            <ds:Reference URI="#_48141811-d3ab-4d1c-b073-9d8b240489ec">
                    <ds:Transform Algorithm="" />
                    <ds:Transform Algorithm="" />
                <ds:DigestMethod Algorithm="" />
        <KeyInfo xmlns="">
    <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"


Wednesday, January 27, 2016

AAD : Azure AD and IDPInitiated

Came across this very interesting post in SO.

Custom SSO With Azure Active Directory.

Note the IDPInitiated section:

"Finally, if your application expects IdP initiated SSO, construct a canned SAML AuthNRequest and save it in a URL - when your organization's users will click on this URL (canned SAML AuthNRequest) - they will get redirected to Azure AD where they will sign-in and then the token will be posted to the application's AssertionConsumerServiceURL - resulting in the user getting signed in. 

You can use the following tool to create a SAML AuthNRequest":

Azure AD doesn't have an IDP Initiated endpoint so this is a neat little trick!


WIF : IDPInitiated and a WS-Fed application

I discussed IDPInitiated here:

ADFS : SAML redirect to application via relayState and loginToRp 

I've been looking at a case where IDPInitiated is used to a WS-Fed application.

The use case is:

IDP --> SAML --> ADFS --> WS-Fed --> Application

IDPInitiated is a SAML feature not supported in WS-Fed but it works in ADFS if you use the RPID construct.

If you set the RPID to the identifier of an RP in ADFS, the user will use IDPInitiated on their IDP to authenticate and this will go to ADFS, ADFS will see they are authenticated and pass the token onto the RP seamlessly.

However, you will get:

ID4216: The ClaimType '' must be of format 'namespace'/'name'.

The reason is discussed here:

AD FS 2.0: The Admin Event Log Shows Error 111 with System.ArgumentException: ID4216

Essentially, WS-Fed uses a SAML 1.1 token  and SAML 2.0 uses a SAML 2.0 token and SAML 1.1 is far stricter on the claim type.

It requires:

<Attribute Name="">
    <AttributeValue> </AttributeValue>

Instead of:

<saml:Attribute Name="EmailAddress"
    <saml:AttributeValue      xsi:type="xs:string"></saml:AttributeValue>

Note the difference in the attribute name formats.

Apart from this WIF breaks because all the classes expect the stricter URI form.

To sort this out:

On the IDP side, just pass everything through:

 => issue(claim = c);

On the RP side, you needs to do a pass-through but using a custom rule e.g.

c:[Type == "EmailAddress"]
 => issue(Type = "", Value = c.Value);

That will keep WIF happy :-)


Thursday, January 21, 2016

OAuth : Microsoft OWIN (for Identity) and ADAL are not general purpose libraries

I'm seeing a lot of confusion about this.

Microsoft has OWIN client libraries for OpenID Connect / OAuth2.

It also has ADAL - Active Directory Authentication Library (used mainly for native devices).

Both implement the protocols so you would think that you can use these to hook up to any server that implements OpenID Connect / OAuth.

Except that you would be wrong.

OAuth is notorious for incompatibility so you can't really mix and match.

These libraries are aimed at a specific use case i.e. the server is either Azure AD or ADFS.

In addition, the profile is hybrid flow so if your server doesn't implement that you are already out of luck,

Which is not to say that it won't work in some cases.

e.g. IdentityServer 3 does implement the hybrid flow.

Refer : IdentityServer : The WebApp-OpenIDConnect-DotNet Azure AD sample.

Here I show how to use the OWIN library to connect to IdentityServer 3. As you can see, I had to make some alterations.


Monday, January 11, 2016

ADFS : SAML redirect to application via relayState and loginToRp

This post follows on from:

IDP Initiated Sign-on to SAML SP using SAML IDP

Prior reading:

The question is around having a SAML IDP (Salesforce), ADFS as the RP-STS and multiple SAML RP.

Users may authenticate with either AD (via ADFS) or via Salesforce.

The easy way is to use RP Initiated but that wasn't an option.

In the link above, there is a useful tool to generate the relayState.

There are three text boxes:


The article is somewhat confusing because the third text box refers both to a string to be passed to the application and the ADFS identifier of the application.

However, the use case we want i.e.

Identity provider security token server (STS) -> relying party STS (configured as a SAML-P endpoint) -> SAML relying party App

is supported.

I tried this with two ADFS - both v3.0.

So ADFS IDP = adfs-idp
ADFS RP-STS = adfs-rp-sts
Application ID = appid

which leads to:


and the URL is:


So the user should authenticate on adfs-idp, be redirected to adfs-rp-sts, be already authenticated and then be redirected to the application.

However, I could not get this to work. I kept getting:

MSIS7001: The passive protocol context was not found or not valid. If the context was stored in cookies, the cookies that were presented by the client were not valid. Ensure that the client browser is configured to accept cookies from this website and retry this request.

If I left the third text box empty and removed the empty "RelayState=", I get:


So the user should authenticate on adfs-idp, be redirected to adfs-rp-sts, be already authenticated and then select the application from the dropdown, This works.

For AD authentication, we can use the form at the top of the article i.e. using the loginToRp parameter.

This gives:


So the user should authenticate on adfs-rp-sts and be redirected to the application, This works.

Or we can take a completely different approach (albeit with ADFS 3.0) as per:

ADFS 3.0: Playing with Authentication

where you can use:


where you can configure any of your relying parties to use specific claims provider(s).


Just to call out @RobM's summary from the forum question above:

"If you have a SAML IDP and a WS-Federation SP, you can use a URL constructed in the following manner to sign in:

If you have a SAML IDP and a SAML SP, the URL looks like so:

Note that with WS-federation, the flow is ADFS --> IDP --> ADFS --> RP

With SAML only, the flow is IDP --> ADFS --> RP"


Thursday, January 07, 2016

OWIN : ASP.NET MVC application with multiple authentication options

There are many questions over at stackoverflow around this.

I have Forms Based Authentication (FBA) but I want to add other providers as well.

In WIF days, this was really difficult to do since WIF added events into the events pipeline.

With the advent of OWIN, this is a whole lot easier.

Assume you have ASP.NET Identity but you also want social (e.g. Facebook)  and WS-Fed and SAMLp. (p for the protocol as opposed to the token)

My starting point was Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#).

I wasn't that interested in the social side - my interest was more the enterprise federation and I used Active Directory Federation services (ADFS) v3.0 as my IDP. This supports both WS-Fed and SAML.

The key point in creating the project is to leave "Change Authentication" as "Individual User Accounts". This gives you ASP.NET Identity as a starting point.

You need the following NuGet packages:




The code in Startup.Auth.CS looks like:

// Uncomment the following lines to enable logging in with third party login providers

    clientId: "1234",
    clientSecret: "1234");

    consumerKey: "1234",
    consumerSecret: "1234");

    appId: "1234",
    appSecret: "1234");

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
    ClientId = "1234",
    ClientSecret = "1234"

var adfs = new WsFederationAuthenticationOptions
    AuthenticationType = "Federation",
    Caption = "ADFS WS-Fed",
    MetadataAddress = "https://xxx/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "urn:owinmultirp"


var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
    SPOptions = new SPOptions
        EntityId = new EntityId("https://xxx/OWINMultiAuthWebApplication/saml/")

    AuthenticationType = "KentorAuthServices",
    Caption = "ADFS - SAML2p",

Uri metadataURI = new Uri("https://xxx/federationmetadata/2007-06/federationmetadata.xml");

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://xxx/adfs/services/trust"),
        MetadataUrl = metadataURI,
        LoadMetadata = true,


You need the following includes:

    using Kentor.AuthServices;
    using Kentor.AuthServices.Owin;
    using System.IdentityModel.Metadata;

So there is just the one application but on the ADFS side we need to configure two RP; one for WS-Fed and one for SAML. Logically, ADFS thinks there are two separate applications.

There is no metadata so ADFS configuration has to be done manually.


Set identifier to:


Set endpoint to:

    https://xxx/OWINMultiAuthWebApplication/ or whatever for your app.

Set up claims rules as per IdentityServer : ASP.NET MVC application to idsrv3 to ADFS.


Set identifier to:


Set endpoint as per:

Under the "Advanced" tab, set the "Secure Hash Algorithm" to SHA-1.

Set up claims rules as per IdentityServer : ASP.NET MVC application to idsrv3 to ADFS.

Just to reiterate - you must have a NameID claim for both protocols.

Login screen

Run up the application and you should see something like:

So now you have FBA plus a whole host of other options - all in the same application!


ADFS : Support for SAML Scoping

With WS-Fed, the whr parameter allows you to specify the home realm and hence avoid the Home Realm Discovery screen.

What is the SAML equivalent?

There is relayState but relayState means two things:
  • IDPInitiated - similar to whr
  • SPIntitiated - used for context (similar to WS-Fed wtcx).
So for SPIntitiated, you're out of luck.

SAML also provides the Scoping parameter which performs a similar function.

An AuthnRequest using Scoping would look like e.g.

<samlp:AuthnRequest ID="_2528098e-4326-4fe2-83fd-72544c485420"
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://xxx/</saml:Issuer>
    <samlp:NameIDPolicy AllowCreate="true" />
    <samlp:Scoping ProxyCount="10">
            <samlp:IDPEntry ProviderID="" />

Unfortunately, ADFS doesn't support this in v2.0 / v 2.1 / v3.0.

Hopefully, it will in v4.0.


Wednesday, December 16, 2015

IdentityServer : The WebApp-OpenIDConnect-DotNet Azure AD sample

I use this sample a lot - Azure-Samples/active-directory-dotnet-webapp-openidconnect.

I've also been looking at idsrv3 lately - mainly from the enterprise PoV i.e. WS-Fed and SAML

idserv3 also supports modern authentication i.e. OpenID Connect and OAuth2.

So I wondered if this sample would work on idsrv3?

As per OpenID Connect Hybrid Flow and IdentityServer v3:

"Lastly, hybrid flow is the only flow supported by the Microsoft OpenID Connect authentication middleware (in combination with a form post response mode)"

Hybrid flow is described in the article. The above tells us that idsrv3 has to be hooked up using the hybrid flow.

(BTW - the idsrv3 equivalent sample is here - Clients/MVC OWIN Client (Hybrid)).

Turns out the changes are minimal - as you would expect.

In Startup.Auth.cs:

private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

string authority = String.Format(CultureInfo.InvariantCulture, aadInstance);

public void ConfigureAuth(IAppBuilder app)
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

        new OpenIdConnectAuthenticationOptions
            ClientId = clientId,
            Authority = authority,
            RedirectUri = postLogoutRedirectUri,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            Notifications = new OpenIdConnectAuthenticationNotifications

The only change was to add the RedirectUri.

Note that I tried to minimise the changes so I kept the AADInstance variable even though Azure AD is not involved.


<add key="ida:ClientId" value="katanaclientad" />
<!--<add key="ida:Tenant" value="[Enter tenant name, e.g.]" />-->
<add key="ida:AADInstance" value="https://localhost:44333/core" />
<add key="ida:PostLogoutRedirectUri" value="https://localhost:44320/" />

On the idsrv3 side, we need a new Client:


new Client
    ClientName = "Katana Hybrid Client Demo - AAD Sample",
    Enabled = true,
    ClientId = "katanaclientad",
    ClientSecrets = new List<Secret>
        new Secret("secret".Sha256())

    Flow = Flows.Hybrid,
    AllowedScopes = new List<string>
    ClientUri = "",
    LogoUri = [snip]

    RequireConsent = false,
    AccessTokenType = AccessTokenType.Reference,
    RedirectUris = new List<string>

    PostLogoutRedirectUris = new List<string>

The changes to display the claim are as per: IdentityServer : Identity Server 3 as a WS-Federation IDP with an ASP.NET MVC application.

 So we navigate to the sample, click the "Sign In" link. it redirects to idsrv3, we can authenticate with "alice / alice" or "bob / bob", back to the sample, click the Contact tab and the claims are displayed as below:

Claim Type Claim Value
nonce 635858209323.....Tk5YjYtNjU1NzU2ZWU4MzU5
iat 1450224140
c_hash 0ibKE6.....uZcbGR_A 818727 password 1450224139 idsrv
name Alice Smith Alice Smith
iss https://localhost:44333/core
aud katanaclientad
exp 1450224440
nbf 1450224140


Monday, December 14, 2015

AAD : The default WS-Federation claims

I have an ASP.NET RP using OWIN WS-Fed to talk to an ADFS instance and this ADFS instance has Azure AD as a CP.

For reference, this is the default claims set from AAD:

Claims from ClaimsIdentity

Claim Type Claim Value QY7TN_h.....vFbw9IKD-nY 4ef13bb.....a8291aeded 8f803ba.........63-eacba54 joe joe bloggs Mozilla/5.0 (Windows NT 6.3; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0 /adfs/ls/ true 0000.....0-0080e7 https://my-pc/WebApp-ADFS-DotNet/ 2015-12-13T19:12:58.920Z

Sadly, there is no way currently to alter this default set other than to use Microsoft Graph to get the claims yourself.

Note that because AAD is built on a Graph platform, a lot of the values are actually GUID's.


ADFS : Passing all the claims over

If you are troubleshooting / debugging an IDP - RP claims setup in ADFS, a neat trick is to just have the following custom rule on both the IDP and RP:

c:[] => issue(claim = c);

This passes all the claims over so you can see exactly how the user is set up in the repository you are authenticating against.

Then you can fine-tune the claims rules to pass-through / transform or whatever.


Friday, December 11, 2015

ADFS : Using Azure AD

I'm frequently asked about using Azure AD together with ADFS, AAD is becoming far more prevalent, mainly because of the popularity of Office 365 (which uses AAD under the hood).

There are a number of ways of doing this.

The first is the DirSync / AAD Connect route where the AD attributes are synched up to AAD. The AAD tenant becomes a federated tenant and relies on ADFS for authentication.

The second is where ADFS is added as a custom SAML application - refer : Configuring single sign-on to applications that are not in the Azure Active Directory application gallery. 

I don't recommend doing it this way - just including this for completeness.

The third way - and by far the easiest - is just to federate them. Import the AAD metadata (the endpoint link is at the bottom of an AAD Application) into ADFS and then configure AAD as per the second scenario in WAAD AS IdP.

Note that the URI is http rather than https (because it's the entityID).

This is also documented in this post (just ignore the SharePoint stuff).