c# - tutorial - So sichern Sie eine ASP.NET-Web-API




web api custom response (4)

Die Web-API hat ein Attribut [Authorize] , um Sicherheit zu bieten. Dies kann global eingestellt werden (global.asx)

public static void Register(HttpConfiguration config)
{
    config.Filters.Add(new AuthorizeAttribute());
}

Oder pro Controller:

[Authorize]
public class ValuesController : ApiController{
...

Natürlich kann Ihre Art der Authentifizierung variieren und Sie möchten möglicherweise Ihre eigene Authentifizierung durchführen. In diesem Fall können Sie nützlich sein, das Attribut Autorize zu erben und es so zu erweitern, dass es Ihren Anforderungen entspricht:

public class DemoAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (Authorize(actionContext))
        {
            return;
        }
        HandleUnauthorizedRequest(actionContext);
    }

    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        challengeMessage.Headers.Add("WWW-Authenticate", "Basic");
        throw new HttpResponseException(challengeMessage);
    }

    private bool Authorize(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        try
        {
            var someCode = (from h in actionContext.Request.Headers where h.Key == "demo" select h.Value.First()).FirstOrDefault();
            return someCode == "myCode";
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Und in deinem Controller:

[DemoAuthorize]
public class ValuesController : ApiController{

Hier ist ein Link zu anderen benutzerdefinierten Implementierungen für WebApi-Autorisierungen:

http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/

Ich möchte einen RESTful- Webdienst mithilfe der ASP.NET-Web-API erstellen, die von Drittentwicklern für den Zugriff auf die Daten meiner Anwendung verwendet wird.

Ich habe ziemlich viel über OAuth gelesen und es scheint der Standard zu sein, aber ein gutes Beispiel mit Dokumentation zu finden, die erklärt, wie es funktioniert (und das tatsächlich funktioniert!) Scheint unglaublich schwierig zu sein (besonders für einen Neuling von OAuth).

Gibt es ein Beispiel, das tatsächlich erstellt und funktioniert und zeigt, wie dies implementiert wird?

Ich habe zahlreiche Beispiele heruntergeladen:

  • DotNetOAuth - Dokumentation ist hoffnungslos aus der Perspektive eines Neulings
  • Thinktecture - kann es nicht bauen

Ich habe mir auch Blogs angeschaut, die ein einfaches tokenbasiertes Schema (wie this ) vorschlagen - das scheint das Rad neu zu erfinden, aber es hat den Vorteil, konzeptionell ziemlich einfach zu sein.

Es scheint so viele Fragen wie SO zu geben, aber keine guten Antworten.

Was machen alle in diesem Raum?


Hast du DevDefined.OAuth ausprobiert?

Ich habe es verwendet, um meine WebApi mit 2-Legged OAuth zu sichern. Ich habe es auch erfolgreich mit PHP-Clients getestet.

Es ist ziemlich einfach, Unterstützung für OAuth mit dieser Bibliothek hinzuzufügen. So können Sie den Anbieter für die ASP.NET MVC-Web-API implementieren:

1) Holen Sie den Quellcode von DevDefined.OAuth: https://github.com/bittercoder/DevDefined.OAuth - die neueste Version ermöglicht OAuthContextBuilder Erweiterbarkeit.

2) Erstellen Sie die Bibliothek und verweisen Sie sie in Ihrem Web-API-Projekt.

3) Erstellen Sie einen benutzerdefinierten Context Builder, um das Erstellen eines Kontexts aus HttpRequestMessage :

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http;
using System.Web;

using DevDefined.OAuth.Framework;

public class WebApiOAuthContextBuilder : OAuthContextBuilder
{
    public WebApiOAuthContextBuilder()
        : base(UriAdjuster)
    {
    }

    public IOAuthContext FromHttpRequest(HttpRequestMessage request)
    {
        var context = new OAuthContext
            {
                RawUri = this.CleanUri(request.RequestUri), 
                Cookies = this.CollectCookies(request), 
                Headers = ExtractHeaders(request), 
                RequestMethod = request.Method.ToString(), 
                QueryParameters = request.GetQueryNameValuePairs()
                    .ToNameValueCollection(), 
            };

        if (request.Content != null)
        {
            var contentResult = request.Content.ReadAsByteArrayAsync();
            context.RawContent = contentResult.Result;

            try
            {
                // the following line can result in a NullReferenceException
                var contentType = 
                    request.Content.Headers.ContentType.MediaType;
                context.RawContentType = contentType;

                if (contentType.ToLower()
                    .Contains("application/x-www-form-urlencoded"))
                {
                    var stringContentResult = request.Content
                        .ReadAsStringAsync();
                    context.FormEncodedParameters = 
                        HttpUtility.ParseQueryString(stringContentResult.Result);
                }
            }
            catch (NullReferenceException)
            {
            }
        }

        this.ParseAuthorizationHeader(context.Headers, context);

        return context;
    }

    protected static NameValueCollection ExtractHeaders(
        HttpRequestMessage request)
    {
        var result = new NameValueCollection();

        foreach (var header in request.Headers)
        {
            var values = header.Value.ToArray();
            var value = string.Empty;

            if (values.Length > 0)
            {
                value = values[0];
            }

            result.Add(header.Key, value);
        }

        return result;
    }

    protected NameValueCollection CollectCookies(
        HttpRequestMessage request)
    {
        IEnumerable<string> values;

        if (!request.Headers.TryGetValues("Set-Cookie", out values))
        {
            return new NameValueCollection();
        }

        var header = values.FirstOrDefault();

        return this.CollectCookiesFromHeaderString(header);
    }

    /// <summary>
    /// Adjust the URI to match the RFC specification (no query string!!).
    /// </summary>
    /// <param name="uri">
    /// The original URI. 
    /// </param>
    /// <returns>
    /// The adjusted URI. 
    /// </returns>
    private static Uri UriAdjuster(Uri uri)
    {
        return
            new Uri(
                string.Format(
                    "{0}://{1}{2}{3}", 
                    uri.Scheme, 
                    uri.Host, 
                    uri.IsDefaultPort ?
                        string.Empty :
                        string.Format(":{0}", uri.Port), 
                    uri.AbsolutePath));
    }
}

4) Verwenden Sie dieses Lernprogramm zum Erstellen eines OAuth-Anbieters: http://code.google.com/p/devdefined-tools/wiki/OAuthProvider . Im letzten Schritt (Zugriff auf ein geschütztes Ressourcen-Beispiel) können Sie diesen Code in Ihrem AuthorizationFilterAttribute Attribut verwenden:

public override void OnAuthorization(HttpActionContext actionContext)
{
    // the only change I made is use the custom context builder from step 3:
    OAuthContext context = 
        new WebApiOAuthContextBuilder().FromHttpRequest(actionContext.Request);

    try
    {
        provider.AccessProtectedResourceRequest(context);

        // do nothing here
    }
    catch (OAuthException authEx)
    {
        // the OAuthException's Report property is of the type "OAuthProblemReport", it's ToString()
        // implementation is overloaded to return a problem report string as per
        // the error reporting OAuth extension: http://wiki.oauth.net/ProblemReporting
        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
            {
               RequestMessage = request, ReasonPhrase = authEx.Report.ToString()
            };
    }
}

Ich habe meinen eigenen Provider implementiert, also habe ich den obigen Code nicht getestet (außer natürlich den WebApiOAuthContextBuilder den ich in meinem Provider verwende), aber es sollte gut funktionieren.


Wenn Sie Ihre API in einem Server auf Server-Art sichern möchten (keine Umleitung zur Website für die 2-Being-Authentifizierung). Sie können das OAuth2 Client Credentials Grant-Protokoll anzeigen.

https://dev.twitter.com/docs/auth/application-only-auth

Ich habe eine Bibliothek entwickelt, mit der Sie diese Art von Unterstützung für Ihr WebAPI einfach hinzufügen können. Sie können es als NuGet-Paket installieren:

https://nuget.org/packages/OAuth2ClientCredentialsGrant/1.0.0.0

Die Bibliothek zielt auf .NET Framework 4.5 ab.

Nachdem Sie das Paket zu Ihrem Projekt hinzugefügt haben, wird eine Readme-Datei im Stammverzeichnis Ihres Projekts erstellt. Sie können sich diese Readme-Datei ansehen, um zu sehen, wie Sie dieses Paket konfigurieren / verwenden.

Prost!


in Fortsetzung zu @ Cuong Les Antwort wäre mein Ansatz, Wiederholungsangriffe zu verhindern

// Verschlüsseln Sie die Unix-Zeit auf Client-Seite mit dem freigegebenen privaten Schlüssel (oder Benutzer-Passwort)

// Senden Sie es als Teil des Anfrage-Headers zum Server (WEB-API)

// Entschlüsselung der Unix-Zeit am Server (WEB-API) mit dem freigegebenen privaten Schlüssel (oder dem Benutzerpasswort)

// Überprüfen Sie den Zeitunterschied zwischen der Unixzeit des Clients und der Unixzeit des Servers, sollte nicht größer als x Sek. Sein

// Wenn Benutzer-ID / Hash-Passwort korrekt sind und die entschlüsselte UnixTime innerhalb von x Sek. der Serverzeit liegt, dann ist dies eine gültige Anfrage





asp.net-web-api