2017-08-23 4 views
1

J'ai implémenté le flux OAuth2 client_credentials dans notre application MVC. Notre application MVC est en fait la ressource dans ce scénario. J'ai eu beaucoup de mal à sécuriser un échantillon pour ce cas d'utilisation spécifique, puisque ce flux est principalement utilisé pour l'accès à l'API, mais je l'ai quand même fait.
Je voudrais partager avec vous certains des détails d'implémentation pour vous demander des informations sur les vulnérabilités que je ne connais peut-être pas. Je ne suis en aucun cas un expert en sécurité, ce qui m'a amené ici.
Dans .NET Framework 4.5.2 J'ai utilisé les bibliothèques Microsoft.Owin v3.0.1. Je sais qu'il existe de nouvelles façons de configurer ce genre de choses (.NET Core et IdentityServer4 par exemple), mais comme je l'ai dit, j'avais de la difficulté à trouver un échantillon viable pour ce cas spécifique, alors j'ai fait de mon mieux.
I mis en œuvre un fournisseur:Vulnérabilités lors de l'utilisation des informations d'identification du client et du middleware OWIN OAuth

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider 
{ 
    private ClientService clientService; 

    public ApplicationOAuthProvider() 
    { 
     this.clientService = new ClientService(); 
    } 

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     string clientId; 
     string clientSecret; 
     context.TryGetFormCredentials(out clientId, out clientSecret); 

     if (clientId == "XXXX" && clientSecret == "XXXXX") 
     { 
      context.Validated(clientId); 
     } 

     return base.ValidateClientAuthentication(context); 
    } 

    public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context) 
    { 
     var client = clientService.GetClient(context.ClientId); 
     var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); 
     oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, client.ClientName)); 
     var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties()); 
     context.Validated(ticket); 
     //context.OwinContext.Response.Headers.Add("Access-Control-All‌​ow-Origin", new[] { "*" }); 
     return base.GrantClientCredentials(context); 
    } 

avec le code de démarrage suivant:

public partial class Startup 
{ 
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } 

    static Startup() 
    { 
     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      TokenEndpointPath = new PathString("/Token"), 
      Provider = new ApplicationOAuthProvider(), 
      AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60), 
      //AllowInsecureHttp = true, 
      AuthenticationMode = AuthenticationMode.Active, 

     }; 
    } 

    public void ConfigureAuth(IAppBuilder app) 
    { 
     app.UseCors(CorsOptions.AllowAll) 
      .UseOAuthBearerTokens(OAuthOptions); 
     //app.UseOAuthBearerTokens(OAuthOptions); 
    } 
} 

public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

     ConfigureAuth(app); 
    } 
}  

puis créé une application client qui est aussi un site Web et finalement obtenu l'accès à la (application MVC) des ressources. La ressource n'a pas d'utilisateurs, donc pas d'écran de connexion. La ressource (maintenant) a un point de terminaison de jeton. L'application cliente envoie une demande au point de terminaison de jeton avec ses informations d'identification et, après l'authentification, utilise ce jeton dans les requêtes suivantes à la ressource.
J'ai trouvé 2 façons différentes d'utiliser ce jeton pour accéder.

  • Incluez le jeton d'accès dans l'en-tête de la demande. OU
  • Inclure le jeton d'accès en tant que paramètre de forme

Mes questions sont au sujet des vulnérabilités à ce scénario:
En supposant que toutes les communications entre l'application client et le serveur se passent sur des canaux sécurisés (https) et le client L'application est capable de maintenir les informations d'identification de manière sécurisée, quelles sont les chances qu'un badge d'accès puisse être obtenu ou intercepté? Ou y at-il des méthodes incluses dans ce flux (ou peut-être un autre flux OAuth) qui incluent également la vérification du client? Je me rends compte que le client est déjà authentifié via client_id/client_secret, mais quand je demande la vérification, je demande l'origine de la requête (en supposant bien sûr que la méthode de vérification n'inclut pas la vérification de quelque chose qui peut être usurpé) par un utilisateur malveillant).
Y a-t-il une étape supplémentaire de vérification que j'aurais peut-être ratée - parce qu'il y a beaucoup d'information là-bas et que j'ai fait de mon mieux, mais je ne peux pas prétendre avoir une bonne compréhension de tout J'ai lu jusqu'ici.
S'il y a une étape de vérification supplémentaire que j'ai manquée, comment cela s'intègre-t-il dans ce flux (client_credentials)?

Merci, Carrie

Répondre

1

j'ai trouvé 2 différentes façons d'utiliser ce jeton pour y avoir accès.

  • Incluez le jeton d'accès dans l'en-tête de la demande.OU
  • Inclure le jeton d'accès en tant que paramètre de forme

Cela signifie que votre jeton d'accès est de type jeton porteur (donc, vous pouvez également utiliser un troisième moyen d'envoyer le jeton d'accès: en utilisant la méthode GET avec un paramètre de requête).

Quelles sont les chances qu'un jeton d'accès puisse être obtenu ou intercepté?

Ou y a-t-il des méthodes incluses dans ce flux (ou peut-être un autre flux OAuth) qui incluent également la vérification du client?

Vous avez un jeton de support, donc la RFC-6750 s'applique. La section d'atténuation des menaces répond à vos questions:

  • d'abord, votre jeton d'accès peut être divulguée si la version de TLS entre votre application client et le serveur d'autorisation (pour obtenir le jeton), et entre les l'application client et le serveur de ressources (pour donner le jeton), présentent un défaut de sécurité (extrait: Cela nécessite que l'interaction de communication entre le client et le serveur d'autorisation, ainsi que l'interaction entre le client et le serveur de ressources, utilisent la confidentialité Comme TLS est obligatoire à mettre en œuvre et à utiliser avec cette spécification, il s'agit de l'approche préférée pour empêcher le rejet de jeton. osure via le canal de communication.)

  • d'autre part, une autre façon pour votre jeton d'accès à divulguer est l'utilisation d'un accélérateur TLS. Comme indiqué dans la même section de la RFC: Dans certains déploiements, y compris ceux utilisant des équilibreurs de charge, la connexion TLS au serveur de ressources se termine avant le serveur réel qui fournit la ressource. Cela pourrait laisser le jeton non protégé entre le serveur frontal où la connexion TLS se termine et le serveur principal qui fournit la ressource.

Il existe d'autres façons de divulguer le jeton d'accès.

La solution n'est pas d'implémenter un autre flux OAuth mais d'appliquer les recommandations de la section 5.3 de la RFC. En résumé, les principales recommandations sont les suivantes:

  • toujours utiliser TLS,
  • validate chaînes de certificats TLS,
  • utiliser le chiffrement jeton en plus de l'utilisation de la protection TLS: par exemple, chiffrer le jeton un secret partagé entre l'application client et le serveur de ressources,
  • ne stocke pas porteur de jetons dans les cookies,
  • question des jetons au porteur de courte durée,
  • d'émettre des jetons au porteur (utilisation de restriction d'audience).

Ceci n'est pas dans la RFC mais j'ajouterais cette recommandation: utiliser l'authentification mutuelle. Cela signifie que l'application cliente doit posséder un certificat X.509 qui doit être vérifié par le serveur de ressources. Cela est possible dans le flux Oauth2 que vous avez choisi, car l'application client est connue du serveur de ressources (avec certains flux alternatifs, cela ne peut pas être fait).

+1

Merci beaucoup d'avoir pris le temps de l'écrire. Cela a vraiment aidé à attacher beaucoup de choses ensemble pour moi! – codenewbie