Custom authentication w WCF

W celu zaimplementowania customowego uwierzytelniania użytkownika chcącego wykonać operacje w serwisie WCF, można skorzystać z Username Password Authentication.

Rozwiązanie to wymaga dodatkowo posiadania/wygenerowania certyfikatu X509.

Korzystamy z bindingu wsHttpBinding z włączanym zabezpieczeniem transmisji na poziome komunikatów.
Dodatkowo właściwość clientCredentialType ustawiamy na UserName.

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

Następnie w serwice behaviors definiujemy sekcje serviceCredentials, gdzie ustawiamy userNameAuthentication i określamy, że chcemy sami dostarczyć metodę do walidacji loginu i hasła.
W metodzie tej zaimplementujemy logikę, w której sprawdzimy czy podany login i hasło zgadzają się.
Ustawiamy tutaj również serviceCertificate.

      <serviceBehaviors>        
        <behavior name="CalculatorBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="CalculatorServiceLibrary.CredentialsValidator, CalculatorServiceLibrary" />
            <serviceCertificate findValue="MyComp" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>

Metoda do walidacji sprowadza się do zaimplementowanie metody Validate z abstrakcyjnej klasy UserNamePasswordValidator.

    public class CredentialsValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))

                throw new SecurityTokenException("Username and password required");

            if (!IsCredentialValid(userName, password))
            {
                throw new FaultException("Wrong username or password ");
            }
        }

        private bool IsCredentialValid(string userName, string password)
        {
             //Sprawdzenia czy podany userName i password zgadzają się
        }
    }

Samo przekazanie username i password do serwisu sprowadza się do ustawienia właściwości ClientCredentials.UserName w obiekcie proxy.
Użytkownik podaje je w momencie kiedy loguje się np. do aplikacji webowej.

  proxy.ClientCredentials.UserName.UserName = "login";
  proxy.ClientCredentials.UserName.Password = "password";
Advertisements