Programmering

Implementere HTTP-autentisering i Web API

I denne artikkelen vil jeg presentere en diskusjon om implementering av HTTP-autentisering i Web API. Det er to måter du kan implementere HTTP-autentisering i Web Api på. Disse inkluderer:

  • Skjemaautentisering
  • Grunnleggende autentisering

Vi vil ikke betrakte Windows-godkjenning som en gjennomførbar strategi, da du ikke kan eksponere tjenesten din over Internett hvis du utnytter Windows-autentisering.

Sikre Web Api ved hjelp av skjemaautentisering

Skjemaautentisering bruker ASP.Net-medlemskapsleverandøren og bruker standard HTTP-informasjonskapsler i stedet for autorisasjonsoverskriften. Skjemaautentisering er ikke så REST-vennlig da den bruker informasjonskapsler, og klientene vil trenge å administrere informasjonskapsler for å konsumere tjenester som benytter seg av skjemaautentisering, som er sårbar for forfalskningsangrep på tvers av nettstedet. Dette er grunnen til at du trenger å implementere CSRF-tiltak hvis du bruker skjemaautentisering. Skjemaautentisering bruker ikke kryptering for å sikre brukerens legitimasjon. Derfor er dette ikke en sikker strategi med mindre du kjører Web API over SSL.

Sikker web-API ved hjelp av grunnleggende autentisering

Grunnleggende autentisering sender brukerens legitimasjon i klage-tekst over ledningen. Hvis du skulle bruke grunnleggende autentisering, bør du bruke Web-API-et over et Secure Socket Layer (SSL). Når du bruker grunnleggende autentisering, vil vi sende brukerens legitimasjon eller godkjenningstoken i overskriften til HTTP-forespørselen. Tjenesten på serversiden må analysere overskriften for å hente godkjenningstokenet. Hvis forespørselen ikke er en gyldig forespørsel, returnerer serveren HTTP 401, noe som betyr et uautorisert svar.

La oss utforske hvordan vi kan utføre grunnleggende autentisering ved hjelp av et handlingsfilter. For å gjøre dette, bør du opprette en klasse som stammer fra System.Web.Http.Filters.ActionFilterAttribute klasse som vist nedenfor:

offentlig klasse BasicAuthenticationAttribute: System.Web.Http.Filters.ActionFilterAttribute

    {

private Boolean IsUserValid (ordbok legitimasjon)

        {

if (legitimasjon ["Brukernavn"]. Lik ("joydip") && legitimasjon ["Passord"]. Lik ("joydip123"))

returner sant;

returner falsk;

        }

privat ordbok ParseRequestHeaders (System.Web.Http.Controllers.HttpActionContext actionContext)

        {

Ordboksopplysninger = ny ordbok ();

var httpRequestHeader = actionContext.Request.Headers.GetValues ​​("Authorization"). FirstOrDefault ();

httpRequestHeader = httpRequestHeader.Substring ("Autorisasjon" .Length);

streng [] httpRequestHeaderValues ​​= httpRequestHeader.Split (':');

streng brukernavn = Encoding.UTF8.GetString (Convert.FromBase64String (httpRequestHeaderValues ​​[0]));

strengpassord = Encoding.UTF8.GetString (Convert.FromBase64String (httpRequestHeaderValues ​​[1]));

credentials.Add ("Brukernavn", brukernavn);

legitimasjon.Add ("Passord", passord);

retur legitimasjon;

        }

offentlig overstyring ugyldig OnActionExecuting (System.Web.Http.Controllers.HttpActionContext actionContext)

        {

prøve

            {

if (actionContext.Request.Headers.Authorization == null)

                {

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.Unauthorized);

                }

ellers

                {

Ordboksopplysninger = ParseRequestHeaders (actionContext);

                     hvis (IsUserValid (legitimasjon))

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.OK);

ellers

actionContext.Response = nytt System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.Unauthorized);

                 }

            }

å fange

            {

actionContext.Response = nytt System.Net.Http.HttpResponseMessage

(System.Net.HttpStatusCode.InternalServerError);

            }

        }

    }

Vi sjekker om autorisasjonsoverskriften er til stede; hvis ikke, returneres et HTTP 401- eller "uautorisert" svar.

Neste trinn er å validere brukerlegitimasjonen som sendes via overføringen fra autorisasjonsforespørselen fra klienten. Før vi gjør det, bør vi vite hvordan Web API skal kalles fra klienten. For dette har jeg utarbeidet en testmetode. Testmetoden bruker HttpClient klasse for å ringe Web API. Merk at brukernavnene konverteres til Base64-strengformat før de sendes. Testmetoden er gitt nedenfor.

[Testmetode]

offentlig ugyldig BasicAuthenticationTest ()

        {

streng brukernavn = Convert.ToBase64String (Encoding.UTF8.GetBytes ("joydip"));

strengpassord = Convert.ToBase64String (Encoding.UTF8.GetBytes ("joydip123"));

HttpClient-klient = ny HttpClient ();

client.DefaultRequestHeaders.Authorization = ny AuthenticationHeaderValue ("Autorisasjon", brukernavn + ":" + passord);

var resultat = client.GetAsync (ny Uri ("// localhost // api / standard /")). Resultat;

Assert.IsTrue (result.IsSuccessStatusCode);

        }

Som du kan se i kodebiten ovenfor, sendes brukerlegitimasjonen ved hjelp av autorisasjonsoverskriften.

Nå som klienten er klar, la oss fullføre implementeringen av BasicAuthenicationFilter klasse. Inne i OnActionExecuting metoden vi trenger å analysere topptekstverdien i denne klassen og sjekke om legitimasjonen som leveres fra klienten samsvarer. For nå, la oss anta at brukernavnet og passordet har verdiene på joydip og joydip123, henholdsvis (de er hardkodede). Her er den komplette koden til BasicAuthenticationFilter klasse som inneholder validering av brukerlegitimasjonen.

offentlig klasse BasicAuthenticationAttribute: System.Web.Http.Filters.ActionFilterAttribute

    {

offentlig overstyring ugyldig OnActionExecuting (System.Web.Http.Controllers.HttpActionContext actionContext)

        {

prøve

            {

if (actionContext.Request.Headers.Authorization == null)

                {

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.Unauthorized);

                }

ellers

                {

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.InternalServerError);

var httpRequestHeader = actionContext.Request.Headers.GetValues ​​("Authorization"). FirstOrDefault ();

httpRequestHeader = httpRequestHeader.Substring ("Autorisasjon" .Length);

streng [] httpRequestHeaderValues ​​= httpRequestHeader.Split (':');

streng brukernavn = Encoding.UTF8.GetString (Convert.FromBase64String (httpRequestHeaderValues ​​[0]));

strengpassord = Encoding.UTF8.GetString (Convert.FromBase64String (httpRequestHeaderValues ​​[1]));

hvis (brukernavn.Equals ("joydip") && password.Equals ("joydip123"))

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.OK);

ellers

actionContext.Response = nytt System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.Unauthorized);

                }

            }

å fange

            {

actionContext.Response = ny System.Net.Http.HttpResponseMessage (System.Net.HttpStatusCode.InternalServerError);

            }

        }

    }

I kontrollerklassen din bør du spesifisere attributtet riktig. Merk at BasicAuthentication attributt her refererer til BasicAuthenticationAttribute klasse vi implementerte.

    [BasicAuthentication]

offentlig klasse DefaultController: ApiController

    {

offentlig IEnumerable Get ()

        {

returner ny streng [] {"Joydip", "Kanjilal"};

        }

    }

Nå, litt konfigurasjon --- du må konfigurere attributtet slik at anrop til kontrolleren din blir filtrert riktig for at autentiseringen skal fungere.

 offentlig statisk klasse WebApiConfig

    {

public static void Register (HttpConfiguration config)

        {

config.MapHttpAttributeRoutes ();

config.Routes.MapHttpRoute (

navn: "DefaultApi",

routeTemplate: "api / {controller} / {id}",

standardinnstillinger: ny {id = RouteParameter.Optional}

            );

config.Formatters.Remove (config.Formatters.XmlFormatter);

GlobalConfiguration.Configuration.Filters.Add (ny BasicAuthenticationAttribute ());

        }

    }

Og du er ferdig! Når du utfører testsaken, går testen.

Du bør uansett sørge for at legitimasjonen ikke er hardkodet; i stedet bør de lagres i en database, og du bør hente dem og validere i OnActionExecuting metoden for BasicAuthenticationAttribute klasse.