75 votes

Enregistrement de connexions externes à l'API Web 2 à partir de plusieurs clients API avec OWIN Identity

Je voudrais l'architecture suivante (j'ai fait le nom du produit pour cet exemple):

Web API 2 application s'exécutant sur un serveur http://api.prettypictures.com

MVC 5 client application qui s'exécute sur un autre serveur http://www.webpics.com

Je voudrais www.webpics.com client application pour utiliser les Jolies Images de l'API:

  • Créez de nouveaux comptes avec le nom d'utilisateur et mot de passe
  • Créez de nouveaux comptes avec Facebook/Google/Twitter/Microsoft
  • Journal en
  • Récupérer des photos

Tous les travaux ci-dessus à l'exception de l'enregistrement externe des comptes avec Facebook, Google etc.

Je ne peux pas travailler sur l'écoulement correct de créer un externe compte d'un client, utilisateur de l'API.

J'ai étudié la plupart des documents disponibles sur le flux d'authentification, comme ceci: enter image description here

J'ai lu à peu près tout ce que je peux sur le nouveau modèle d'Identité dans OWIN.

J'ai examiné le SPA modèle dans Visual Studio 2013. Il montre comment faire la plupart de ce dont j'ai besoin, mais uniquement lorsque le client et l'API sont sur le même hôte; si je veux de plusieurs clients à accéder à mon API et d'être en mesure de permettre aux utilisateurs de s'inscrire via Google etc. il ne fonctionne pas et aussi loin que je peux dire à la OWIN le flux d'authentification des pauses.

En voici le déroulement:

  • L'utilisateur accède à www.webpics.com/Login
  • www.webpics.com appels api.prettypictures.com/Account/ExternalLogins (avec un returnUrl set pour revenir à un rappel à www.webpics.comet affiche l'résultant des liens de l'utilisateur
  • L'utilisateur clique sur "Google"
  • Le navigateur redirige vers api.prettypictures.com/Account/ExternalLogin avec le nom du fournisseur, etc.
  • L'API de ExternalLogin action instancie un défi à google.com
  • Le navigateur est redirigé vers google.com
  • L'utilisateur entre son nom d'utilisateur et le mot de passe (si elles ne sont pas déjà connecté à google.com)
  • google.com aujourd'hui il présente la cote de sécurité: "api.prettypictures.com" souhaitez avoir accès à votre adresse e-mail, nom, femme, enfants, etc. Est-ce OK?
  • L'utilisateur clique sur "Oui" et est pris api.prettypictures.com/Account/ExternalLogin un cookie est que Google a mis.

C'est là que j'ai bloqué. Ce qui est censé se passer est en quelque sorte l'application client doit être informé que l'utilisateur est authentifié avec succès avec google.com et être soumis à un usage unique code d'accès à l'échanger pour un jeton d'accès plus tard. L'application client doit avoir la possibilité, si nécessaire, demander à l'utilisateur un nom d'utilisateur à associer à leurs google.com connexion.

Je ne sais pas comment faciliter cette.

En fait, à ce stade, le navigateur finit par s'assit à la api.prettypictures.com/Account/ExternalLogin point de terminaison après le rappel de Google. L'API est signé pour Google, mais le client ne sait pas comment le gérer. Dois-je la pipe que cookie www.webpics.com?

Dans le SPA de l'application, il est fait via AJAX et google.com retourne un jeton comme un fragment d'URL et tout fonctionne très bien, parce que tout se trouve sur un domaine. Mais qui défie bien de la point d'avoir une "API" que plusieurs clients peuvent utiliser pleinement.

À l'aide!

46voto

Pinpoint Points 486

Mise à jour: les choses ont changé depuis que j'ai écrit ce post en janvier: MSFT de la sortie de leur officielles OpenID connect client middleware et j'ai travaillé dur avec @manfredsteyer d'adapter la OAuth2 serveur d'autorisation construit en Katana à OpenID connect. Cette combinaison résulte en un beaucoup plus facile et beaucoup plus puissante solution qui ne nécessite pas de client personnalisé code et est 100% compatible avec la norme OAuth2/OpenID connect clients. Les différentes étapes que j'ai mentionné en janvier peut maintenant être remplacé par quelques lignes:

Serveur:

app.UseOpenIdConnectServer(new OpenIdConnectServerOptions {
    Issuer = "http://localhost:55985/",
    AllowInsecureHttp = true,
    SigningCredentials = credentials,

    Provider = new CustomOpenIdConnectServerProvider(),
    AuthorizationCodeProvider = new AuthorizationCodeProvider()
});

Client:

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

    ClientId = "myClient",
    ClientSecret = "secret_secret_secret",
    RedirectUri = "http://localhost:56854/oidc"
});

Vous pouvez trouver tous les détails (et les différents échantillons) sur le dépôt GitHub:

https://github.com/AspNet-OpenIdConnect-Server/Owin.Security.OpenIdConnect.Server https://github.com/AspNet-OpenIdConnect-Server/Owin.Security.OpenIdConnect.Server/tree/dev/samples/Mvc

Note que c'est encore expérimental: si vous trouvez un bug, n'hésitez pas à ouvrir un nouveau ticket. Vous pouvez également vous connecter sur https://jabbr.net/#/rooms/owin si vous avez besoin d'aide ou envie de partager vos remarques.


Josh, vous êtes certainement sur la bonne voie et de vos délégués/authentification fédérée mise en œuvre semble assez bon (j'imagine que vous avez utilisé la prédéfinis OWIN middleware d' Microsoft.Owin.Security.Facebook/Google/Twitter).

Ce que vous devez faire est de créer votre propre personnalisé OAuth2 serveur d'autorisation. Vous avez beaucoup d'options pour y parvenir, mais le plus simple est probablement de brancher l' OAuthAuthorizationServerMiddleware dans votre OWIN de Démarrage de la classe. Vous le trouverez dans l' Microsoft.Owin.Security.OAuth de package Nuget.

Alors que la meilleure pratique serait de créer un projet distinct (souvent appelé "AuthorizationServer"), personnellement, je préfère l'ajouter à mon "projet API" quand il n'est pas destiné à être utilisé dans de nombreuses API (ici, vous devez l'insérer dans le projet d'hébergement "api.prettypictures.com").

Vous trouverez un grand échantillon dans le Katana référentiel:

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,
    }
});

N'hésitez pas à parcourir l'ensemble du projet pour voir comment l'autorisation de formulaire de consentement a été mis en œuvre à l'aide de simples Rasoir fichiers. Si vous préférez un plus haut niveau de cadre comme ASP.NET MVC ou NancyFX, créer votre propre AuthorizationController de contrôleur et d' Authorize méthodes (assurez-vous d'accepter les deux GET et POST) et l'utilisation de l'Attribut de Routage pour correspondre à la AuthorizeEndpointPath définis dans votre OAuth2 serveur d'autorisation (ie. [Route("oauth2/authorize")] dans mon exemple, où j'ai changé l' AuthorizeEndpointPath utilisation oauth2/ comme un chemin d'accès de base).

L'autre chose que vous devez faire est d'ajouter une OAuth2 autorisation du client dans votre application web. Malheureusement, il n'y a pas de générique OAuth2 soutien des clients dans le Katana, et vous aurez à construire votre propre. J'ai personnellement soumis une proposition pour le Katana de l'équipe, mais il a été refusé. Mais pas de panique, c'est assez facile à faire:

Copie les fichiers nécessaires à partir de la Microsoft.Owin.De sécurité.Google référentiel s'y trouve: https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs

Vous aurez besoin d' GoogleOAuth2AuthenticationHandler, GoogleOAuth2AuthenticationMiddleware, GoogleOAuth2AuthenticationOptions, GoogleAuthenticationExtensions (vous devrez supprimer les 2 premières méthodes correspondant à la Google OpenID mise en œuvre), en IGoogleOAuth2AuthenticationProvider, GoogleOAuth2ReturnEndpointContext, GoogleOAuth2AuthenticationProvider, GoogleOAuth2AuthenticatedContext et GoogleOAuth2ApplyRedirectContext. Une fois que vous avez inséré ces fichiers dans votre projet d'hébergement "webpics.com", de les renommer et de modifier en conséquence l'autorisation et le jeton d'accès aux points de terminaison d'URL en GoogleOAuth2AuthenticationHandler pour correspondre à celles que vous avez définies dans votre OAuth2 serveur d'autorisation.

Ensuite, ajouter l'Utilisation de la méthode à partir de votre renommé/personnalisée GoogleAuthenticationExtensions de votre OWIN de Démarrage de la classe. Je suggère d'utiliser AuthenticationMode.Active , de sorte que vos utilisateurs seront directement redirigés vers votre API OAuth2 autorisation d'extrémité. Ainsi, vous devez supprimer le "api.prettypictures.com/Account/ExternalLogins" aller-retour et de laisser le OAuth2 middleware client de modifier les réponses 401 pour rediriger les clients de votre API.

Bonne chance. Et n'hésitez pas si vous avez besoin de plus d'infos ;)

-10voto

Teddy Points 347

Je suis un peu confus.

OAuth 2.0 n'est pas complexe, il y a trois rôles: l'utilisateur, le client du site et de ressources du serveur de site. Et son but est très clair, l'utilisateur envie de l'accès à la ressource protégée avec des opérations sur site client.

Donc, pour revenir à ta question, ce qui ne l'agent utilisateur? Si vous voulez ouvrir votre Api à des tiers site authentifié, OAuth 2.0 est ce que vous avez besoin. Si ce n'est pour un tiers du site, juste pour l'utilisateur final, le déploiement de l'api à un sous-domaine du site est mieux, et si dans un autre domaine, de la SCRO(html5), ok.

Pour google OAuth:

  1. Utilisateur final, cliquez sur "se connecter avec un compte google" lien sur votre site.
  2. Redirigé vers google de la page de connexion, et de saisie de nom d'utilisateur et mot de passe, puis cliquez sur "autoriser" bouton.
  3. Redirigé vers des url de callback(liées à votre application) sur votre site d'autoriser code.
  4. L'échange d'un pion autoriser code, alors vous pouvez appeler des api google.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X