Rejestracja zewnętrznych loginów Web API 2 od wielu klientów API z identyfikacją OWIN

Chciałbym mieć następującą architekturę (wymyśliłem nazwę produktu dla tego przykładu):

Aplikacja Web API 2 działająca na jednym serwerze http://api.prettypictures.com

Aplikacja kliencka MVC 5 działająca na innym serwerze http://www.webpics.com

Chciałbym www.webpics.com aplikacja kliencka do korzystania z interfejsu API Pretty Pictures:

  • zarejestruj nowe konta za pomocą nazwy użytkownika i hasła
  • Zarejestruj nowy konta na Facebook/Google / Twitter / Microsoft
  • Zaloguj się
  • Odzyskaj Zdjęcia

Wszystkie powyższe prace z wyjątkiem rejestracji zewnętrznych kont w Facebook, Google itp.

Nie mogę wypracować poprawnego przepływu, aby utworzyć zewnętrzne konto od oddzielnego Użytkownika Klienta API.

Przestudiowałem większość dokumentów dostępnych w procesie uwierzytelniania, takich jak: Tutaj wpisz opis obrazka

Przeczytałem prawie wszystko, co mogę na temat nowej tożsamości model w owinie.

Zbadałem szablon SPA w Visual Studio 2013. Pokazuje, jak zrobić większość tego, czego potrzebuję, ale tylko wtedy, gdy klient i API są na tym samym hoście; jeśli chcę, aby wielu klientów uzyskało dostęp do mojego API i było w stanie pozwolić użytkownikom zarejestrować się przez Google itp. to nie działa i z tego co wiem to przerwy w przepływie uwierzytelniania OWIN.

Oto jak dotąd przepływ:

  • użytkownik przegląda do www.webpics.com/Login
  • www.webpics.com wywołania api.prettypictures.com/Account/ExternalLogins (with a returnUrl set to go back to a callback at www.webpics.com ) i wyświetla wynikowe linki do Użytkownika
  • użytkownik klika "Google"
  • przeglądarka przekierowuje do api.prettypictures.com/Account/ExternalLogin z nazwą dostawcy itp.
  • działanie API ExternalLogin tworzy instancję a wyzwanie do google.com
  • przeglądarka jest przekierowywana do google.com
  • użytkownik wprowadza swoją nazwę użytkownika i hasło (jeśli nie jest jeszcze zalogowany do google.com )
  • google.com teraz prezentuje poświadczenie bezpieczeństwa: "api.prettypictures.com" chcesz uzyskać dostęp do swojego adresu e-mail, imienia i nazwiska, żony, dzieci itp. Może być?
  • użytkownik kliknie "tak" i zostanie przeniesiony do api.prettypictures.com/Account/ExternalLogin z ciasteczkiem ustawionym przez Google.

Tu utknąłem. Co ma się stać dalej, to w jakiś sposób aplikacja kliencka powinna zostać powiadomiona, że użytkownik pomyślnie uwierzytelnił się za pomocą google.com i otrzymać jednorazowy kod dostępu do wymiany na token dostępu. Aplikacja kliencka powinna mieć możliwość, w razie potrzeby, poproszenia użytkownika o powiązanie nazwy użytkownika z jego google.com login.

Nie wiem jak to ułatwić.

W rzeczywistości w tym momencie przeglądarka kończy usiadł na api.prettypictures.com/Account/ExternalLogin punkt końcowy po wywołaniu zwrotnym od Google. API jest zalogowane dla Google, ale klient nie wie, jak sobie z tym poradzić. Czy powinienem wrzucić to ciastko z powrotem do www.webpics.com ?

W aplikacji SPA odbywa się to poprzez AJAX i google.com zwróci token jako fragment adresu URL i wszystko działa ładnie bo wszystko mieści się w jednej domenie. Ale to zaprzecza w dużej mierze istnieniu "API", z którego wielu Klientów może w pełni korzystać.

Pomocy!

Author: joshcomley, 2014-01-16

1 answers

OpenID OpenID connect: wiele się zmieniło od czasu napisania tego postu w styczniu: MSFT wydało oficjalne oprogramowanie pośredniczące klienta OpenID connect i ciężko pracowałem z @manfredsteyer nad dostosowaniem serwera autoryzacji OAuth2 wbudowanego w katanę do OpenID connect. Ta kombinacja daje o wiele łatwiejsze i bardziej wydajne rozwiązanie, które nie wymaga żadnego niestandardowego kodu klienta i jest w 100% kompatybilne ze standardowymi klientami OAuth2/OpenID connect. Poszczególne kroki, o których wspomniałem w styczniu, mogą być teraz zastąpiony przez kilka linijek:

Serwer:

app.UseOpenIdConnectServer(options =>
{
    options.TokenEndpointPath = new PathString("/connect/token");
    options.SigningCredentials.AddCertificate(certificate);

    options.Provider = new CustomOpenIdConnectServerProvider();
});

Klient:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "http://localhost:55985/",

    ClientId = "myClient",
    ClientSecret = "secret_secret_secret",
    RedirectUri = "http://localhost:56854/oidc"
});
Wszystkie szczegóły (i różne sample) znajdziesz w repozytorium GitHub:]}

Https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server

Https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Nancy


Josh, jesteś na dobrej drodze, a Twój uwierzytelnianie delegowane/federacyjne implementacja wydaje się całkiem dobra (domyślam się, że użyłeś predefiniowanego oprogramowania pośredniczącego OWIN z Microsoft.Owin.Security.Facebook/Google/Twitter).

To, co musisz zrobić, to stworzyć własny serwer autoryzacji OAuth2 . Masz wiele opcji, aby to osiągnąć, ale najprostszą z nich jest prawdopodobnie podłączenie OAuthAuthorizationServerMiddleware do klasy startowej OWIN. Znajdziesz go w Microsoft.Owin.Security.OAuth paczce Nuget.

Podczas gdy najlepszą praktyką byłoby stworzenie oddzielnego projektu (często nazywany "AuthorizationServer"), osobiście wolę dodać go do mojego "projektu API", gdy nie ma być używany w wielu API (tutaj trzeba by go wstawić do hostingu projektu "api.prettypictures.com").

Znajdziesz świetną próbkę w repozytorium Katana:

Https://katanaproject.codeplex.com/SourceControl/latest#tests/Katana.Sandbox.WebServer/Startup.cs

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
    AuthorizeEndpointPath = new PathString("/oauth2/authorize"),
    TokenEndpointPath = new PathString("/oauth2/token"),
    ApplicationCanDisplayErrors = true,

    AllowInsecureHttp = true,

    Provider = new OAuthAuthorizationServerProvider
    {
        OnValidateClientRedirectUri = ValidateClientRedirectUri,
        OnValidateClientAuthentication = ValidateClientAuthentication,
        OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
    },
    AuthorizationCodeProvider = new AuthenticationTokenProvider
    {
        OnCreate = CreateAuthenticationCode,
        OnReceive = ReceiveAuthenticationCode,
    },
    RefreshTokenProvider = new AuthenticationTokenProvider
    {
        OnCreate = CreateRefreshToken,
        OnReceive = ReceiveRefreshToken,
    }
});

Nie wahaj się przejrzeć całego projektu, aby zobaczyć, jak formularz zgody autoryzacji został zaimplementowany przy użyciu prostych plików Razor. Jeśli wolisz ramy wyższego poziomu, takie jak ASP.NET MVC lub NancyFX, utwórz własny kontroler AuthorizationController i metody Authorize (upewnij się, że akceptujesz zarówno GET, jak i POST) i użyj trasowania atrybutów, aby dopasować ścieżkę autoryzacji AuthorizeEndpointPath zdefiniowaną w serwerze autoryzacji OAuth2 (tj. [Route("oauth2/authorize")] w mojej próbce, gdzie zmieniłem AuthorizeEndpointPath, aby użyć oauth2/ jako podstawy ścieżki).

Inną rzeczą, którą musisz zrobić, to dodać OAuth2 klient autoryzacji w aplikacji internetowej. Niestety, nie ma ogólnej obsługi klienta OAuth2 w katanie i będziesz musiał zbudować swój własny. Osobiście złożyłem propozycję zespołowi Katany, ale została ona odrzucona. Ale nie panikuj, to raczej łatwe do zrobienia:

Skopiuj odpowiednie pliki z Microsoftu.Owin.Ochrona.Znajduje się tam repozytorium Google: https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs

Będziesz potrzebował GoogleOAuth2AuthenticationHandler, GoogleOAuth2AuthenticationMiddleware, GoogleOAuth2AuthenticationOptions, GoogleAuthenticationExtensions (będziesz musiał usunąć pierwsze 2 metody odpowiadające implementacji Google OpenID), IGoogleOAuth2AuthenticationProvider, GoogleOAuth2ReturnEndpointContext, GoogleOAuth2AuthenticationProvider, GoogleOAuth2AuthenticatedContext i GoogleOAuth2ApplyRedirectContext. Po włożeniu tych plików do hostingu projektu "webpics.com", odpowiednio zmienić ich nazwy i zmienić adres URL autoryzacji i dostępu do tokenów w GoogleOAuth2AuthenticationHandler aby dopasować te, które zdefiniowałeś na swoim serwerze autoryzacji OAuth2.

Następnie Dodaj metodę Use z przemianowanego / niestandardowego GoogleAuthenticationExtensions do swojej klasy startowej OWIN. Sugeruję użycie AuthenticationMode.Active, aby użytkownicy zostali bezpośrednio przekierowani do punktu końcowego autoryzacji API OAuth2. Tak więc, należy stłumić "api.prettypictures.com/Account/ExternalLogins" roundtrip i pozwól oprogramowaniu pośredniczącemu klienta OAuth2 zmienić 401 odpowiedzi, aby przekierować klientów do twojego API.

Powodzenia. Oraz nie wahaj się, jeśli potrzebujesz więcej informacji;)]}
 46
Author: Pinpoint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-30 19:35:01