macOS Sierra in Active Directory integrieren

pexels-photo-58420

In modernen Netzwerken finden sich heute große Anzahl verschiedenen Clientgeräte, darunter auch immer mehr macOS Clients. Die Anbindung an ein Windows Active Diretory erfordert ein paar Skripting Kenntnisse. Im folgenden Code Schnipsel zeigen wir, wie der Domain Join unter macOS Sierra durchzuführen ist.

# Terminal starten
# sudo sh joinDomain.sh
#
#!/bin/bash
domain=exampledomain.de
adUserName=exampleusername
adPass=examplepassword
computerName=examplename



systemsetup -setusingnetworktime on -setnetworktimeserver $domain

#Set ComputerName
scutil --set ComputerName $computerName
scutil --set LocalHostName $computerName
scutil --set HostName $computerName

#Join Domain
dsconfigad -add $domain -force -username "$adUserName" -password "$adPass"

#User Local Home Path
dsconfigad -mobile enable -mobileconfirm disable -localhome enable -useuncpath disable

#Add Domain Admins to Local Admins
dsconfigad -groups "Domain Admins,svc_DSM_RTS,u-ge-ws-admins" -alldomain enable

#Namespace Support
dsconfigad -namespace domain

#SSO
dsconfigad -enablesso

#Name and Password = TRUE | List Of Users = FALSE
sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool FALSE

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;
    }
}