Autenticazione API Web ASP.NET MVC 4 con provider di appartenenze

Ho un progetto ASP.NET MVC 4 che utilizza l’API Web. Sul controller ho impostato la class per richiedere l’authorization utilizzando l’attributo [Autorizza]. Per l’autenticazione, sto utilizzando il provider di appartenenze ASP.NET e il mio set Web.Config è impostato per utilizzare l’autenticazione “Forms”. Qui è dove sono bloccato:

Tutto funziona perfettamente fino al punto in cui ho terminato di testare l’API e voglio proteggere il controller con l’attributo [Autorizza], così posso iniziare a testare l’autenticazione con gli utenti nel mio provider di appartenenza. Quindi accendo Fiddler e faccio la stessa chiamata aggiungendo l’attributo Authorization: Basic insieme a un nome utente: password dal mio provider di appartenenze in questo modo:

inserisci la descrizione dell'immagine qui

La risposta che ottengo è 401 non autorizzato e sotto “Auth” ottengo “Nessuna intestazione autentica WWW è presente.” Poi mi rendo conto che l’API sta cercando una chiave codificata SHA1. Quindi accendo un generatore SHA1 da una ricerca e ottengo un hash per il mio nome utente: password e aggiorno l’intestazione della richiesta in questo modo:

inserisci la descrizione dell'immagine qui

Anche questo non funziona e ottengo gli stessi risultati. Inoltre ho ovviamente bisogno di una sorta di “chiave segreta condivisa” da utilizzare con il server per decodificare il mio nome utente / password.

Quindi le mie domande:

  1. Come ottengo questa chiave dal server (o in questo caso Virtual IIS che funziona su VS 2012).
  2. Come posso usarlo per effettuare chiamate autenticate in Fiddler utilizzando nomi utente / password da un provider di appartenenze ASP.NET.
  3. Come userò questo nella mia applicazione client per effettuare le stesse chiamate (C # WPF App).
  4. Questo è il modo migliore per essere combinato con SSL sulle mie chiamate HTTP? Se no, cos’è?

Grazie in anticipo!

    Potresti usare l’autenticazione di base con SSL. Sul lato server potremmo scrivere un gestore delegato personalizzato che verificherà le credenziali interrogando il provider di memebers che abbiamo registrato e, se valido, recupererà i ruoli e imposterà il principal corrente:

    public class BasicAuthenticationMessageHandler : DelegatingHandler { protected override Task 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); } } 

    Quindi registriamo questo gestore in Application_Start :

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

    Ora potremmo avere un controller Api che verrà decorato con l’attributo [Authorize] per garantire che solo gli utenti autenticati possano accedere alle sue azioni:

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

    Bene, ora diamo un’occhiata a un client di esempio:

     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().Result); } } } }