Requesting a SAML token from ADFS in C#

NOTE: The code for my ADFS experiments is available at github

The problem

I set out to integrate a new .net web api project (and the client application consuming it) with ADFS authentication. Since I wanted to understand the nuts and bolts of ADFS tokens & using them with web apis, I chose not to use any “designer tools” in Visual Studio. Here’s what I’d like to achieve:

  • client application authenticates for the first time with username/password
  • use credentials to request security token from ADFS
  • convert the token to JWT format for usage in HTTP headers

Getting the token

Requesting the token is actually pretty easy once you use a little WCF magic (and know your ADFS endpoint). Here is the code for my TokenProvider. Please note that I use the excellent “Thinktecture.IdentityModel” nuget package.

public class ADFSUsernameMixedTokenProvider
{
    private readonly Uri ADFSUserNameMixedEndpoint;

    /// <summary>
    ///
    /// </summary>
    /// <param name="adfsUserNameMixedEndpoint">i.e. https://adfs.mycompany.com/adfs/services/trust/13/usernamemixed </param>
    public ADFSUsernameMixedTokenProvider(Uri adfsUserNameMixedEndpoint)
    {
        this.ADFSUserNameMixedEndpoint = adfsUserNameMixedEndpoint;
    }

    public GenericXmlSecurityToken RequestToken(string username, string password, string relyingPartyId)
    {
        var factory = new WSTrustChannelFactory(
                new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                 new EndpointAddress(this.ADFSUserNameMixedEndpoint));

        factory.TrustVersion = TrustVersion.WSTrust13;

        factory.Credentials.UserName.UserName = username;
        factory.Credentials.UserName.Password = password;

        var rst = new RequestSecurityToken
        {
            RequestType = RequestTypes.Issue,
            AppliesTo = new EndpointReference(relyingPartyId),
            KeyType = KeyTypes.Bearer
        };
        IWSTrustChannelContract channel = factory.CreateChannel();
        GenericXmlSecurityToken genericToken = channel.Issue(rst) as GenericXmlSecurityToken;

        return genericToken;
    }
}

Verhindern der Anmeldung an spezifische Office 365 Mandanten

Letzte Woche kam bei uns folgende Kundenanforderung herein:

Der Kunde erlaubt gewissen Benutzern keinerlei Zugang ins Internet, nun will er aber Office 365 einführen. Generell ist das ja kein Problem, da wir dann einfach nur die spezifischen Office 365 IP Adressen und URLs an den Firewalls bzw. Proxy-Servern freischalten lassen. Nun kam er Kunde aber zu uns zurück mit der Frage, was denn passiert, wenn sich der Benutzer privat einen eigenen Office 365 Mandanten erstellt, und über die dortigen Dienste wie Exchange Online oder OneDrive for Business Daten „durchtunnelt“.

Diese Fragestellung hatten wir bisher nicht, wir fanden Sie aber durchaus legitim und wir haben versucht eine Möglichkeit zu finden eine Whitelisting von spezifischen Tenants bzw. deren UPN Suffixe zu realisieren.

Obwohl Microsoft keine Möglichkeit für dieses Szenario bietet haben einen Ansatz erarbeitet. Dieser ist zwar nicht einfach umzusetzen, und „schön“ ist er schon gar nicht, aber im Testlabor hat es funktioniert:

Voraussetzung dafür ist, dass der HTTPS Verkehr des Clients IMMER durch eine intelligente Contentfiltering Lösung gejagt werden muss, die in der Lage ist den HTTPS Traffic aufzubrechen und hier konfigurierbare Rulesets anzuwenden

mslogin

Mann müsste auf diesem Proxy dann auf die URL „https://login.microsoftonline.com/common/userreal“ filtern, und jeglichen Traffic abbrechen, der in dieser URL nach dem Parameter „user=“ nicht eine der gewünschten Office 365 Tenants des Kunden enthält.

Hier ein Beispiel URL so einer Anmeldung:

https://login.microsoftonline.com/common/userrealm/?user=Andreas.Hoetzinger@gab-net.com&api-version=2.1&stsRequest=XXXXXXXXXXXXXXXXXXXXX&checkForMicrosoftAccount=false

Diese URL wird immer nach Verlassen des Login-ID Feldes auf https://login.microsoftonline.com aufgerufen, und dient dazu festzustellen ob die dieser Domänen Suffix überhaupt in O365 registriert ist, und wenn ja ob es sich um eine Federated-Domain oder um eine reine Azure AD Authentifzierung handelt.

Wir haben rausgefunden, dass wenn man diesen Aufruf bei unerwünschten Domains blockt, keine Anmeldung mit Accounts dieser Domäne möglich ist….

Wie gesagt das ganze ist natürlich nicht annähernd 100 % ausgetestet, wäre aber ein Ansatz.

lock

Microsoft muss Daten aus EU-Rechenzentrum nicht der US-Regierung übergeben

Ein großer Sieg für die US-Cloudindustrie und damit auch für uns!

Wie aktuell gemeldet wird, hat ein US-Berufungsgericht die Entscheidung eines untergeordneten Gerichts auf dem Jahre 2014 aufgehoben: Microsoft muss keine Daten aus seinem in Irland gehosteten Clouddienst herausgeben.

Endlich schwebt das Damoklesschwert dieses sogenannten „New-York Cases“ nicht mehr über uns! Es wurde höchstrichterlich klargestellt, dass sich ein US-Gericht nicht einfach über internationale Abkommen und Prozeduren hinwegsetzten kann.

Nun müssen wir diese berechtigte Diskussion nicht mehr mit unseren Kunden führen, und freuen uns auf weitere, viele neuen Office 365 und Azure Projekten in Deutschland!

Gericht