Przejdź do treści

DevStyle - Strona Główna
Social-logowanie w .NET. Po co, dlaczego i jak?

Social-logowanie w .NET. Po co, dlaczego i jak?

Maciej Aniserowicz

11 kwietnia 2017

Backend

Po dziś dzień standardowym “pierwszym krokiem” przy tworzeniu wielu aplikacji jest wygenerowanie tabeli Users z kolumnami Username i Password. Ewentualnie, jeśli ktoś jest bardziej wniknięty, to jeszcze Salt. Po co?

Jak to po co? Żeby dać użytkownikom możliwość zalogowania się do aplikacji, prawda? Czyli UWIERZYTELNIENIA. Ale… to chyba najgorszy możliwy sposób.

Dlaczego tego nie robić?

Czy jesteś w stanie zagwarantować, że Twoje dane są tak bezpieczne jak że aż bardzo bezpieczne?
Czy chcesz pisać masę kodu odpowiedzialną za ustawianie, resetowanie i przypominanie haseł?
Czy umiesz zaimplementować tzw. muti-factor authentication (czyli logowanie z pomocą jednorazowych generowanych haseł albo SMSów)?
Czy masz czas na radzenie sobie z niedocierającymi mailami?

Ja, pisząc aplikację prezentującą informacje o Uczestnikach Daj Się Poznać 2017 odpowiedziałem sobie szczerze: nie, nie, i nie. I jeszcze raz NIE.

Alternatywa

Przecież KTOŚ już to zrobił! Niejeden system zaimplementował to wszystko i ma rzesze ludzie dbających o to, by to działało. Ba, te systemy mają miliony użytkowników, na co dzień weryfikujących poprawność wszystkich tych mechanizmów. I ja mogłem tego użyć. Za friko.

W tym tekście przedstawiam krok po kroku “jak zaimplementować logowanie ‘social providerem’ w swojej aplikacji .NET“. Po więcej mięska, z tłem, teorią itd. odsyłam do podcasta: DevTalk#18 – O tożsamości z Tomaszem Onyszko. Bardzo polecam.

Wiele osób ma konto na Facebooku, Google, Twitterze czy MS Live. A jeśli targetujemy programistów to także na GitHub. Nie ma absolutnie żadnego sensu w wymyślaniu koła na nowo. I dodatkowo zmuszaniu ludzi do zakładania kolejnego konta w kolejnym miejscu w internecie.

Jak?

Poniżej w kilku prostych krokach dodamy możliwość uwierzytelnienia się w aplikacji .NETowej (webowej) poprzez Facebook, Google i GitHub. Tak jak można to zrobić na stronie DSP’17.

SimpleAuthentication

Po pierwsze: znajdujemy odpowiednią bibliotekę, która poradzi sobie z kodem infrastrukturalnym. Można to napisać samemu (robiłem to i polecam, fajna zabawa) ale raczej w hobbystycznie, a nie produkcyjnie. W .NET z pomocą przychodzi SimpleAuthentication (kiedyś: World Domination). Działa świetnie, gdy już poradzimy sobie z nienajlepszą dokumentacją i dość mylącymi “projekcikami pobocznymi”.

Wystarczy:

Install-Package SimpleAuthentication.Core

A potem połączenie z odpowiednim frameworkiem. W moim przypadku:

Install-Package SimpleAuthentication.Mvc4

Ewentualnie możemy dorzucić kilka dodatkowych “providerów”, tzw. “extrasów”. Na przykład integracja z GitHubem jest dostępna w tym pakiecie:

Install-Package SimpleAuthentication.ExtraProviders

Login URL

Strona zalogowania jest banalnie prosta, wystarczy wylistować listę wspieranych linków… i ewentualnie podpiąć je pod jakieś ikonki. Facebook będzie wyglądał tak:

<a href="@Url.RedirectToProvider("facebook")"><img src="/Content/social-img/facebook_32.png" alt="Login with your Facebook account." /></a>

I wsio. Wygeneruje to taki URL:

http://example.com/authentication/redirect/facebook

Obsługą tego żądania, odpowiednim redirectem, zajmie się już biblioteka. Użytkownik zostanie przekierowany na stronę Facebooka (albo innego providera), gdzie zaakceptuje co jest do zaakceptowania. A potem wróci do nas i musimy go przytulić, implementując interfejs IAuthenticationCallbackProvider. Przykłady znajdziesz tutaj, na WIKI. Albo poniżej (z tym że to nie robi niczego sensownego):

public class MyAuthenticationCallbackProvider : IAuthenticationCallbackProvider
{
    public ActionResult Process(HttpContextBase context, AuthenticateCallbackData model)
    {
        return new RedirectResult("/", true);
    }

    public ActionResult OnRedirectToAuthenticationProviderError(HttpContextBase context, string errorMessage)
    {
        return new RedirectResult("/", true);
    }
}

To jest moment, w którym otrzymujemy informację: “tak, to faktycznie jest ziomeczek posiadający konto na portalu X“. Dostaniemy też jakieś ID, username, czasami e-mail, czasami link do fotki… I musimy coś z tym zrobić.

CO zrobić? To zależy. Ja dodaję te dane do własnej bazki, by mieć “na później”. Prawdopodobnie przyda się też wygenerować cookie… czyli zaimplementować nad tym mechanizem normalne Forms Authentication. Ale to nie jest temat na dzisiaj.

Bo jeszcze nie koniec!

Social apps

Skąd Facebook, Google, GitHub czy Twitter wiedzą jaka strona żąda uwierzytelnienia? Z przesłanych tajnych wartości, tzw. “KEY” oraz “SECRET”. Wartości te generowane są dla APLIKACJI.

Chcesz umożliwić zalogowanie się u Ciebie przez Facebooka? Musisz pójść pod ten adres i stworzyć własną aplikację na Facebooku! GitHub? To będzie TUTAJ. A dla Google: TUTAJ.

Nadajemy własną nazwę, dorzucamy ikonkę. Ustawiamy “redirect URL”, czyli dokładny adres, pod którym nasza aplikacja czeka na zalogowanych userów. W moim przypadku, na przykład dla Google, jest to: http://uczestnicy.dajsiepoznac.pl/authentication/authenticatecallback?providerkey=google .

Uwaga: localhost nie wszędzie działa! I czasami można zdefiniować tylko jeden taki URL, więc najwygodniej jest po prostu od razu pchać to do testów na jakiś hosting, pod jakąś domenę.

Z ustawień aplikacji kopiujemy wygenerowane wartości KEY i SECRET i w jakiś sposób transportujemy je do własnego web.configa. Można je tam po prostu wkleić, ale wtedy trzeba uważać na pushe do publicznych repo :).

Kolejne kroki

Najlepsze w całej procedurze jest to, że to już wszystko. Koniec. F5 i działa.

Ktoś zapomniał hasła? Nie interesuje mnie to, hasła nie ma u mnie. Ktoś chce hasło zmienić? Niech idzie tam, gdzie je definiował. Wreszcie: z mojej aplikacji nastąpi wyciek danych? No szkoda, wstyd i w ogóle, ale… nikomu szkoda się nie stanie, bo nie przechowuję żadnych wrażliwych danych!

Polecam, zachęcam, pozdrawiam, całuję.

Zobacz również