Entra ID, Okta ve AD FS ile Delphi'de SAML Tekli Oturum Açma

· Bileşenler
Entra ID, Okta ve AD FS ile Delphi'de SAML Tekli Oturum Açma

Er ya da geç büyük bir müşteri şu soruyu sorar: personelimiz sizin uygulamanıza şirket hesabıyla oturum açabilir mi? Kastettikleri bir kullanıcı adı ve şifre daha değildir. Kastettikleri, zaten her şey için kullandıkları Microsoft Entra ID, Okta veya AD FS oturum açma yöntemidir; kendi şifre politikaları, kendi iki faktörlü doğrulamaları ve birisi ayrıldığında bir hesabı kapatabilecekleri tek bir yer ile birlikte.

Kimlik ekiplerinin beklediği yanıt SAML 2.0'dır. Yeni oturum açma bileşenlerine genel bakış yazısında SAML yalnızca bir paragraf yer buldu. Bu yazı akışın tamamını ele alıyor: TsgcSAMLServiceProvider'ın ne yaptığı, bir oturum açma sayfasının ve Assertion Consumer Service'in kodu, uygulamanızı yaygın identity provider'lara nasıl kaydettireceğiniz ve tüm bunları hiçbir yerde hesabınız olmadan bugün nasıl test edeceğiniz.

SAML Oturum Açma Nasıl Çalışır

Üç taraf yer alır. Uygulamanız service provider'dır (SP). Müşterinin dizini identity provider'dır (IdP). Tarayıcı, mesajları ikisi arasında taşır, bu yüzden sunucunuz ile IdP hiçbir zaman doğrudan konuşmaz.

  1. Kullanıcı oturum açma URL'nizi açar. Uygulamanız bir AuthnRequest oluşturur ve tarayıcıyı IdP'ye yönlendirir.
  2. IdP, şirketin belirlediği şifre, MFA veya koşullu erişim kurallarıyla kullanıcının oturumunu açar.
  3. IdP imzalı bir SAMLResponse ile yanıt verir, ve tarayıcı bunu Assertion Consumer Service (ACS) URL'nize POST eder.
  4. Uygulamanız yanıtı doğrular ve içinde belirtilen kullanıcı için kendi oturumunu oluşturur.

Dördüncü adım, SAML uygulamalarının yanlış gittiği yerdir ve bileşenin sizin adınıza yaptığı kısım tam olarak budur.

Service Provider, Adım Adım

TsgcSAMLServiceProvider bir HTTP sunucusu değildir. SAML mesajlarını oluşturur ve kontrol eder; onu, uygulamanızın zaten sahip olduğu sunucunun istek işleyicisinden çağırırsınız, örneğin bir TsgcWebSocketHTTPServer veya bir TsgcHTTPServer.

EntityID, AssertionConsumerServiceURL ve LoadIdPMetadata başlangıçta bir kez ayarlandığında, oturum açma sayfası ve ACS tek bir istek işleyicisine sığar:

uses
  sgcAuth_SAML_SP;

procedure TMyApp.OnCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  vRelayState, vRequestID: string;
  oResult: TsgcSAMLResult;
begin
  if ARequestInfo.Document = '/saml/login' then
  begin
    // 1. send the browser to the identity provider
    vRelayState := NewRelayState;
    AResponseInfo.Redirect(FSAML.GetAuthnRequestRedirectURL(vRelayState,
      vRequestID));
    // 2. keep the request id, the response must answer it
    AddPendingRequest(vRelayState, vRequestID);
  end
  else if (ARequestInfo.Document = '/saml/acs') and
    SameText(ARequestInfo.Command, 'POST') then
  begin
    // 3. the browser posts SAMLResponse and RelayState back
    vRelayState := ARequestInfo.Params.Values['RelayState'];
    vRequestID := TakePendingRequest(vRelayState);
    oResult := TsgcSAMLResult.Create;
    try
      if FSAML.ProcessResponse(ARequestInfo.Params.Values['SAMLResponse'],
        vRelayState, vRequestID, oResult) then
      begin
        // 4. signed in: create your own session for this user
        CreateUserSession(AResponseInfo, oResult.NameID, oResult.SessionIndex);
        AResponseInfo.Redirect('/');
      end
      else
        AResponseInfo.ResponseNo := 403; // log oResult.ErrorMessage
    finally
      oResult.Free;
    end;
  end;
end;

NewRelayState, AddPendingRequest, TakePendingRequest ve CreateUserSession, kendi kodunuzu temsil eder: bir GUID, RelayState'e göre indekslenmiş ve her istek id'sini yalnızca bir kez veren thread safe bir liste, ve uygulamanızın oturum çerezi. Nitelikler Name=Value satırları olarak gelir, bu yüzden oResult.Attributes.Values['email'] bunlardan birini adına göre okur. Entra ID bunları http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress gibi claim URI'leriyle adlandırır.

RelayState, IdP imzası tarafından kapsanmaz. Onu kendi bekleyen isteğinizi bulmak için bir anahtar olarak kullanın, asla kontrol etmeden yönlendirdiğiniz bir URL olarak değil.

Uygulamanızı Identity Provider'a Kaydettirin

GetMetadata, service provider metadata'sını döndürür: entity ID'niz ve HTTP-POST binding'e sahip ACS URL'niz. Bunları /saml/metadata gibi bir URL'de sunun veya bir dosyaya kaydedin, ve IdP'ye verin. Her identity provider aynı iki değeri ister, SP'nin entity ID'si ve ACS URL'si, bu yüzden aşağıdaki notlar çoğunlukla her konsolun bunları nerede tuttuğuyla ilgilidir. Hepsinde, assertion şifrelemesini kapalı bırakın.

IdP ne olursa olsun, son adım aynıdır: metadata'sını LoadIdPMetadata'ya geçirin. Belge birden çok varlığı tanımladığında, ikinci parametre sizinkini seçer.

ProcessResponse Neyi Kontrol Eder

Bir SAML yanıtı imzalı bir XML belgesidir, ve iyi bilinen SAML güvenlik açıklarının çoğu, bir service provider'a imzalanan şeyden farklı bir şey okutmanın yollarıdır. Bir yanıt yalnızca aşağıdaki kontrollerin her biri geçtiğinde kabul edilir:

Ayrıştırıcı ayrıca DOCTYPE bildirimlerini reddeder, bu yüzden dış varlıklar (external entities) bulunmaz, ve belgenin boyutunu ve iç içe geçme derinliğini sınırlar. Issuer, yapılandırdığınız IdP olmalıdır. İlk başarısız kontrol doğrulamayı durdurur ve nedeni ErrorMessage'da bulunur: bunu loglayın, ve kullanıcıya basit bir “oturum açma başarısız” sayfası gösterin.

Hesap Olmadan Deneyin

SAML'in çalıştığını görmek için bir Entra ID tenant'ına ihtiyacınız yok. Mock SAML, mocksaml.com adresinde ücretsiz bir test identity provider'dır. Herhangi bir service provider'ı kabul eder ve audience ile ACS URL'sini AuthnRequest'ten alır, bu yüzden kaydedilecek hiçbir şey yoktur.

Demos\26.Authentication\03.SAML_ServiceProvider demosu, TsgcWebSocketHTTPServer üzerinde eksiksiz bir service provider'dır ve http://localhost:8090 üzerinde /login, /acs ve /metadata uç noktalarına sahiptir:

  1. Demoyu derleyin ve libcrypto-3.dll ile libssl-3.dll dosyalarını çalıştırılabilir dosyanın yanında tutun. Bunlar demo klasöründe bulunur, ve OpenSSL RSA imzalarını doğrular.
  2. Load IdP metadata'ya tıklayın. Varsayılan kaynak, mocksaml.com metadata URL'sidir.
  3. Start'a, ardından Open Browser'a tıklayın, ve oturum açma bağlantısını izleyin.
  4. mocksaml.com üzerinde, example.com alan adında herhangi bir kullanıcı adı ve herhangi bir şifre yazın.
  5. Tarayıcı ACS'ye geri döner, ve sayfa NameID'yi, SessionIndex'i ve id, email, firstName ve lastName niteliklerini gösterir.

Bu çalıştığında, http://localhost:8090/metadata'yı açın, gerçek IdP'nize kaydedin, demoda IdP metadata'sını yükleyin ve tekrar oturum açın. AD FS için, AD FS yalnızca https kabul ettiğinden, demoyu önce SSL ile çalıştırın.

Mevcut Sınırlamalar

Belgeler

Nereden Edinilir

TsgcSAMLServiceProvider, Delphi ve C++ Builder için sgcWebSockets'in Enterprise ve All-Access sürümlerine dahildir, ve aynı bileşen sgcWebSockets .NET'in de bir parçasıdır. Yalnızca kimlik doğrulamaya ihtiyacınız varsa, sgcAuth paketi bunu diğer oturum açma bileşenleriyle birlikte sunar. Unit adı sgcAuth_SAML_SP'dir, ve bileşeni bir forma yerleştirene kadar mevcut bir uygulamada hiçbir şey değişmez.

Sırada Ne Var

İzleyin

eSeGeCe kanalında “SAML single sign-on in Delphi with Entra ID, Okta and AD FS” başlıklı kısa bir video bulunuyor. Video, IDE'deki kodu ve mocksaml.com'a karşı demo ile yapılan canlı bir oturum açmayı gösteriyor.

Sorularınız, geri bildiriminiz mi var, veya identity provider'ınızı bağlarken yardıma mı ihtiyacınız var? Bizimle iletişime geçin. Kodu yazan kişilerden bir yanıt alacaksınız.