Důvěryhodná fasádní služba

Ukázka TrustedFacade demonstruje, jak přenášet informace o identitě volajícího z jedné služby do druhé, využívající infrastrukturu zabezpečení WCF (Windows Communication Foundation).

Jedná se o běžný způsob návrhu, jak zpřístupnit funkce poskytované službou veřejné síti pomocí fasádní služby. Služba fasády se obvykle nachází v hraniční síti (označované také jako DMZ, demilitarizovaná zóna a monitorovaná podsíť) a komunikuje s back-endovou službou, která implementuje obchodní logiku a má přístup k interním datům. Komunikační kanál mezi fasádní službou a back-endovou službou prochází bránou firewall a obvykle je omezený pouze pro jeden účel.

Tato ukázka se skládá z následujících součástí:

  • Klient kalkulačky

  • Služba rozhraní kalkulačky

  • Back-endová služba kalkulačky

Za validaci žádosti a autentizaci volajícího zodpovídá fasádní služba. Po úspěšném ověření a ověření předá požadavek back-endové službě pomocí řízeného komunikačního kanálu z hraniční sítě do interní sítě. Součástí předané žádosti je, že fasádní služba zahrnuje informace o identitě volajícího, aby back-endová služba mohla tyto informace použít při zpracování. Identita volajícího se přenáší pomocí tokenu Username zabezpečení uvnitř hlavičky zprávy Security . Ukázka používá infrastrukturu zabezpečení WCF k přenosu a extrahování těchto informací z hlavičky Security .

Důležité

Back-endová služba důvěřuje fasádní službě k ověření volajícího. Z tohoto důvodu back-endová služba znovu neověřuje volajícího; používá informace o identitě poskytované službou fasády v předávané žádosti. Kvůli tomuto vztahu důvěryhodnosti musí backendová služba ověřit fasádní službu, aby se zajistilo, že předávaná zpráva pochází ze spolehlivého zdroje – v tomto případě z fasádní služby.

Implementace

V této ukázce jsou dvě komunikační cesty. První je mezi klientem a službou fasády, druhá je mezi fasádní službou a back-endovou službou.

Komunikační cesta mezi klientem a službou Façade Service

Klient na komunikační cestu ke službě fasády používá wsHttpBinding s typem UserName přihlašovacích údajů klienta. To znamená, že klient používá k ověření ve službě fasády uživatelské jméno a heslo a služba fasády používá k ověření klienta certifikát X.509. Konfigurace vazby vypadá jako v následujícím příkladu.

<bindings>
  <wsHttpBinding>
    <binding name="Binding1">
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Služba rozhraní ověřuje volajícího pomocí vlastní UserNamePasswordValidator implementace. Pro demonstrační účely ověřování zajišťuje, aby uživatelské jméno volajícího odpovídalo zadanému heslu. V reálné situaci se uživatel pravděpodobně ověřuje pomocí služby Active Directory nebo vlastního poskytovatele členství ASP.NET. Implementace validátoru se nachází v FacadeService.cs souboru.

public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        // check that username matches password
        if (null == userName || userName != password)
        {
            Console.WriteLine("Invalid username or password");
            throw new SecurityTokenValidationException(
                       "Invalid username or password");
        }
    }
}

Vlastní validátor je nakonfigurovaný tak, aby se používal uvnitř serviceCredentials chování v konfiguračním souboru služby fasády. Toto chování se také používá ke konfiguraci certifikátu X.509 služby.

<behaviors>
  <serviceBehaviors>
    <behavior name="FacadeServiceBehavior">
      <!--The serviceCredentials behavior allows you to define -->
      <!--a service certificate. -->
      <!--A service certificate is used by the service to  -->
      <!--authenticate itself to its clients and to provide  -->
      <!--message protection. -->
      <!--This configuration references the "localhost"  -->
      <!--certificate installed during the setup instructions. -->
      <serviceCredentials>
        <serviceCertificate
               findValue="localhost"
               storeLocation="LocalMachine"
               storeName="My"
               x509FindType="FindBySubjectName" />
        <userNameAuthentication userNamePasswordValidationMode="Custom"
            customUserNamePasswordValidatorType=
           "Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
            FacadeService"/>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

Komunikační cesta mezi službou façade Service a back-endovou službou

Komunikační cesta z fasádní služby do back-endové služby používá customBinding, která se skládá z několika vazebních prvků. Tato vazba zabezpečuje dvě věci. Ověřuje fasádní službu a back-endovou službu, aby se zajistilo, že komunikace je zabezpečená a pochází z důvěryhodného zdroje. Kromě toho také přenáší počáteční identitu volajícího uvnitř tokenu Username zabezpečení. V takovém případě se do back-endové služby přenese pouze počáteční uživatelské jméno volajícího, heslo není součástí zprávy. Důvodem je to, že backend služba důvěřuje fasádní službě, aby ověřila volajícího před předáním požadavku na ni. Vzhledem k tomu, že se služba fasády ověřuje vůči back-endové službě, může back-endová služba důvěřovat informacím obsaženým v předávané žádosti.

Následuje konfigurace vazby pro tuto komunikační cestu.

<bindings>
  <customBinding>
    <binding name="ClientBinding">
      <security authenticationMode="UserNameOverTransport"/>
      <windowsStreamSecurity/>
      <tcpTransport/>
    </binding>
  </customBinding>
</bindings>

Prvek <vazby zabezpečení> se postará o přenos a extrakci uživatelského jména počátečního volajícího. windowsStreamSecurity<> a <tcpTransport> se starají o ověřování rozhraní a backendových služeb a ochranu zpráv.

Aby bylo možné požadavek přeposlat, musí implementace služby fasády poskytnout uživatelské jméno počátečního volajícího, aby infrastruktura zabezpečení WCF mohla toto umístit do přeposlané zprávy. Počáteční uživatelské jméno volajícího je poskytováno v implementaci služby fasády tím, že ho nastavíte ve ClientCredentials vlastnosti instance proxy klienta, kterou služba fasády používá ke komunikaci s back-endovou službou.

Následující kód ukazuje, jak se metoda GetCallerIdentity implementuje na službě fasády. Jiné metody používají stejný vzor.

public string GetCallerIdentity()
{
    CalculatorClient client = new CalculatorClient();
    client.ClientCredentials.UserName.UserName = ServiceSecurityContext.Current.PrimaryIdentity.Name;
    string result = client.GetCallerIdentity();
    client.Close();
    return result;
}

Jak je znázorněno v předchozím kódu, heslo není nastaveno na ClientCredentials vlastnost, je nastaveno pouze uživatelské jméno. Infrastruktura zabezpečení WCF vytvoří token zabezpečení uživatelského jména bez hesla v tomto případě, což je přesně to, co je v tomto scénáři potřeba.

V back-endové službě musí být ověřeny informace obsažené v tokenu zabezpečení uživatelského jména. Ve výchozím nastavení se zabezpečení WCF pokusí namapovat uživatele na účet Systému Windows pomocí zadaného hesla. V tomto případě není k dispozici žádné heslo a back-endová služba není nutná k ověření uživatelského jména, protože ověřování již provedla služba fasády. Pokud chcete tuto funkci implementovat ve WCF, je poskytován vlastní UserNamePasswordValidator, který pouze vynucuje, že uživatelské jméno je zadáno v tokenu a neprovádí žádné další ověřování.

public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        // Ignore the password because it is empty,
        // we trust the facade service to authenticate the client.
        // Accept the username information here so that the
        // application gets access to it.
        if (null == userName)
        {
            Console.WriteLine("Invalid username");
            throw new
             SecurityTokenValidationException("Invalid username");
        }
    }
}

Vlastní validátor je nakonfigurovaný tak, aby se používal uvnitř serviceCredentials chování v konfiguračním souboru služby fasády.

<behaviors>
  <serviceBehaviors>
    <behavior name="BackendServiceBehavior">
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"
           customUserNamePasswordValidatorType=
          "Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
           BackendService"/>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

K extrakci informací o uživatelském jménu a o účtu důvěryhodné služby façade používá implementace backendové služby třídu ServiceSecurityContext. Následující kód ukazuje, jak GetCallerIdentity je metoda implementována.

public string GetCallerIdentity()
{
    // Facade service is authenticated using Windows authentication.
    //Its identity is accessible.
    // On ServiceSecurityContext.Current.WindowsIdentity.
    string facadeServiceIdentityName =
          ServiceSecurityContext.Current.WindowsIdentity.Name;

    // The client name is transmitted using Username authentication on
    //the message level without the password
    // using a supporting encrypted UserNameToken.
    // Claims extracted from this supporting token are available in
    // ServiceSecurityContext.Current.AuthorizationContext.ClaimSets
    // collection.
    string clientName = null;
    foreach (ClaimSet claimSet in
        ServiceSecurityContext.Current.AuthorizationContext.ClaimSets)
    {
        foreach (Claim claim in claimSet)
        {
            if (claim.ClaimType == ClaimTypes.Name &&
                                   claim.Right == Rights.Identity)
            {
                clientName = (string)claim.Resource;
                break;
            }
        }
    }
    if (clientName == null)
    {
        // In case there was no UserNameToken attached to the request.
        // In the real world implementation the service should reject
        // this request.
        return "Anonymous caller via " + facadeServiceIdentityName;
    }

    return clientName + " via " + facadeServiceIdentityName;
}

Informace o účtu služby rozhraní fasády se extrahují pomocí vlastnosti ServiceSecurityContext.Current.WindowsIdentity. Pro přístup k informacím o původním volajícím používá back-endová služba vlastnost ServiceSecurityContext.Current.AuthorizationContext.ClaimSets. Identity Hledá deklaraci identity s typem Name. Toto tvrzení je automaticky generováno infrastrukturou zabezpečení WCF z informací obsažených v bezpečnostním tokenu Username.

Spuštění ukázkového programu

Při spuštění ukázky se požadavky na operace a odpovědi zobrazí v okně konzoly klienta. Stisknutím klávesy ENTER v okně klienta klienta ukončete klienta. Služby můžete vypnout stisknutím klávesy ENTER v oknech konzoly služeb fasády a backendu.

Username authentication required.
Provide a valid machine or domain ac
   Enter username:
user
   Enter password:
****
user via MyMachine\testaccount
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714

Press <ENTER> to terminate client.

Dávkový soubor Setup.bat, který je součástí ukázky scénáře důvěryhodné façade, umožňuje nakonfigurovat server s příslušným certifikátem pro spuštění služby façade, která vyžaduje k zabezpečení ověření pomocí certifikátů pro ověření u klienta. Podrobnosti najdete v postupu nastavení na konci tohoto tématu.

Níže najdete stručný přehled různých částí dávkových souborů.

  • Vytvoření certifikátu serveru

    Následující řádky z dávkového souboru Setup.bat vytvoří certifikát serveru, který se má použít.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
    

    Proměnná %SERVER_NAME% určuje název serveru – výchozí hodnota je localhost. Certifikát je uložen v úložišti LocalMachine.

  • Instalace certifikátu služby façade do důvěryhodného úložiště certifikátů klienta.

    Následující řádek zkopíruje certifikát služby facade do klientského úložiště důvěryhodných certifikátů. Tento krok je povinný, protože certifikáty generované Makecert.exe nejsou implicitně důvěryhodné klientským systémem. Pokud už máte certifikát, který je kořenový v kořenovém certifikátu klienta ( například certifikát vydaný Microsoftem), tento krok naplnění úložiště klientských certifikátů certifikátem pomocí certifikátu serveru se nevyžaduje.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    

Jak nastavit, sestavit a spustit ukázku

  1. Ujistěte se, že jste provedli instalační proceduru One-Time pro ukázky Windows Communication Foundation.

  2. Pokud chcete sestavit verzi C# nebo Visual Basic .NET řešení, postupujte podle pokynů v Sestavení ukázek Windows Communication Foundation.

Pro spuštění ukázky na stejném počítači

  1. Ujistěte se, že cesta obsahuje složku, ve které se nachází Makecert.exe.

  2. Spusťte Setup.bat z ukázkové instalační složky. Tím se nainstalují všechny certifikáty potřebné pro spuštění ukázky.

  3. V samostatném okně konzoly spusťte BackendService.exe z adresáře \BackendService\bin.

  4. V samostatném okně konzole spusťte FacadeService.exe z adresáře \FacadeService\bin.

  5. Spusťte Client.exe z \client\bin. Aktivita klienta se zobrazí v aplikaci konzoly klienta.

  6. Pokud klient a služba nemůžou komunikovat, přečtěte si Tipy pro řešení potíží v ukázkách WCF.

Úklid po vzorku

  1. Po dokončení spuštění ukázky spusťte Cleanup.bat ve složce s ukázkami.