43 votes

ASP.NET MVC 4 Web API d'Authentification avec l'Adhésion à un Fournisseur de

J'ai un ASP.NET MVC 4 Projet à l'aide de l'API Web. Sur le contrôleur, j'ai mis la classe de sorte que l'autorisation à l'aide de l'attribut [Authorize]. Pour l'Authentification, je suis en utilisant le ASP.NET Fournisseur d'appartenances et de mon Web.Config de jeu à utiliser "les Formes de l'Authentification". C'est là que je suis bloqué:

Tout fonctionne très bien jusqu'au moment où j'en ai fini avec les essais de l'API, et je tiens à assurer le contrôleur avec l'attribut [Authorize] afin que je puisse commencer à faire des tests d'authentification à l'encontre des utilisateurs de mon Fournisseur d'appartenances. Donc j'ai le feu au Fiddler et de faire la même appeler l'ajout de l'Autorisation:Base de l'attribut avec un nom d'utilisateur:mot de passe de mon fournisseur d'appartenances comme suit:

enter image description here

La réponse que je reçois est 401 non autorisé et sous "Auth", j'obtiens "Non-Tête WWW-Authenticate est présent." Puis je me rends compte que l'API est à la recherche d'un SHA1 clé codée. Donc je lance un SHA1 générateur à partir d'une recherche et obtenir une valeur de hachage pour mon nom d'utilisateur:mot de passe et de mettre à jour mon en-Tête de Requête comme ceci:

enter image description here

Cela ne fonctionne pas non plus et j'obtiens les mêmes résultats. Aussi, j'ai évidemment besoin d'une sorte de "clé secrète partagée" à utiliser avec le serveur pour décoder mon nom d'utilisateur/mot de passe.

Donc mes questions:

  1. Comment puis-je obtenir cette clé à partir du serveur (ou dans ce cas-IIS Virtuel en cours d'exécution hors VS 2012).
  2. Comment puis-je l'utiliser pour faire des appels Authentifiés dans un violon à l'aide de noms d'utilisateur/mots de passe à partir d'un ASP.NET Fournisseur d'appartenances.
  3. Comment vais-je utiliser dans mon application client de faire les mêmes appels (C# WPF Application).
  4. Est-ce la meilleure pratique en la matière lorsqu'il est combiné avec SSL sur mon HTTP appels? Si non c'est quoi?

Merci à l'avance!

68voto

Darin Dimitrov Points 528142

Vous pouvez utiliser l'authentification de base avec SSL. Du côté serveur, nous pourrions écrire une coutume de déléguer gestionnaire qui permettra de vérifier les informations d'identification par l'interrogation de la memebership fournisseur que nous avons enregistré, et si elle est valable, récupérer les rôles et définir les principaux:

public class BasicAuthenticationMessageHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var authHeader = request.Headers.Authorization;

        if (authHeader == null)
        {
            return base.SendAsync(request, cancellationToken);
        }

        if (authHeader.Scheme != "Basic")
        {
            return base.SendAsync(request, cancellationToken);
        }

        var encodedUserPass = authHeader.Parameter.Trim();
        var userPass = Encoding.ASCII.GetString(Convert.FromBase64String(encodedUserPass));
        var parts = userPass.Split(":".ToCharArray());
        var username = parts[0];
        var password = parts[1];

        if (!Membership.ValidateUser(username, password))
        {
            return base.SendAsync(request, cancellationToken);
        }

        var identity = new GenericIdentity(username, "Basic");
        string[] roles = Roles.Provider.GetRolesForUser(username);
        var principal = new GenericPrincipal(identity, roles);
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }

        return base.SendAsync(request, cancellationToken);
    }
}

Nous avons ensuite enregistrer ce gestionnaire d' Application_Start:

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new BasicAuthenticationMessageHandler()
);

Maintenant, nous pourrions avoir une Api contrôleur qui sera décoré avec l'attribut [Authorize] pour s'assurer que seuls les utilisateurs authentifiés peuvent accéder à ses actions:

[Authorize]
public class ValuesController : ApiController
{
    public string Get()
    {
        return string.Format("Hello {0}", User.Identity.Name);
    }
}

Bien, maintenant, regardons un exemple de client:

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

class Program
{
    static void Main()
    {
        // since for testing purposes I am using IIS Express
        // with an invalid SSL certificate I need to desactivate
        // the check for this certificate.
        ServicePointManager.ServerCertificateValidationCallback += 
            (sender, certificate, chain, sslPolicyErrors) => true;

        using (var client = new HttpClient())
        {
            var buffer = Encoding.ASCII.GetBytes("john:secret");
            var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(buffer));
            client.DefaultRequestHeaders.Authorization = authHeader;
            var task = client.GetAsync("https://localhost:44300/api/values");
            if (task.Result.StatusCode == HttpStatusCode.Unauthorized)
            {
                Console.WriteLine("wrong credentials");
            }
            else
            {
                task.Result.EnsureSuccessStatusCode();
                Console.WriteLine(task.Result.Content.ReadAsAsync<string>().Result);
            }
        }
    }
}

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