it-swarm.com.de

Zugriff auf Post- oder Get-Parameter in benutzerdefinierter Berechtigung MVC4 Web Api

Ist es möglich, über das HttpActionContext-Objekt auf Parameter zuzugreifen oder Parameter abzurufen? 

Ich habe eine Reihe von Sensoren, die Daten auf einem Webserver protokollieren, der eine REST - API liefert. Ich möchte eine Art Authentifizierung/Autorisierung einführen, indem die Sensoren ihre Hardware-ID in die Daten aufnehmen und dann in einer Datenbank nachsehen, ob die ID vorhanden ist oder nicht. Da die API viele Web-API-Aktionsmethoden bietet, würde ich idealerweise ein benutzerdefiniertes Berechtigungsattribut verwenden

public class ApiAuthorizationFilter : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        return false;
    }
}

Wie kann ich auf den Beitrag zugreifen und Daten aus dem actionContext abrufen?

EDIT: Beispiel für POST

POST /Api/api/ActionMethod/ HTTP/1.1\r\n
Content-Type: application/json\r\n
Host: localhost\r\n
Accept: */*\r\n
Content-Length:52\r\n
\r\n
{"Id": '121a222bc', "Time": '2012-02-02 12:00:00'}\r\n

Einen schönen Tag noch!

54
olif

Aufgrund seines Wesens sieht das AuthoriseAttribute so aus, als würde es in der Pipeline aufgerufen, bevor die Modellbinder und die Parameterbindungen ausgeführt wurden. Sie haben auch Probleme, wenn Sie auf Request.Content zugreifen und daraus lesen. Dies kann nur einmal ausgeführt werden . Wenn Sie es in Ihrem Attribut auth versuchen, können Sie den mediaTypeFormater beschädigen.

in WebAPI kann der Anforderungshauptteil (ein HttpContent) ein schreibgeschützter, unbegrenzter, nicht gepufferter, nicht wiederaufwickelbarer Stream sein.

Update Es gibt verschiedene Möglichkeiten, den Ausführungskontext anzugeben ... http://msdn.Microsoft.com/en-us/library/system.web.http.filters.filterscope(v= vs.108) .aspx . Das AuthoriseAttribute ist "Global" und wird daher zu früh getroffen, um auf die Aktionsinformationen zuzugreifen.

Wenn Sie auf das Modell und die Parameter zugreifen möchten, können Sie Ihre Vorgehensweise leicht ändern und stattdessen einen OnActionExecuting-Filter (Filterbereich "Aktion") verwenden und basierend auf Ihrer Validierung einen 401 oder 403 werfen. 

Dieser Filter wird später im Ausführungsprozess aufgerufen, und Sie haben daher vollen Zugriff auf die gebundenen Daten. 

Sehr einfaches Beispiel unten:

public class ApiAuthorizationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        Foo model = (Foo)actionContext.ActionArguments["model"];
        string param1 = (string)actionContext.ActionArguments["param1"];
        int param2 = (int)actionContext.ActionArguments["param2"];

        if (model.Id != "1")
            throw new HttpResponseException(System.Net.HttpStatusCode.Forbidden);

        base.OnActionExecuting(actionContext);
    }
}

Beispiel Controller:

public class Foo
{
    public string Id { get; set; }
    public DateTime Time { get; set; }
}

public class FoosController : ApiController
{
    // PUT api/foos/5
    [ApiAuthorizationFilter]
    public Foo Put(int id, Foo model, [FromUri]string param1 = null, int? param2 = null)
    {
        return model;
    }
}

Was die anderen Antworten sagten ... Sie haben Recht, wenn Sie auf alles zugreifen können, was Sie über die URL benötigen, erhalten Sie über die Anfrage Informationen. Ich denke jedoch, dass das Modell und der Inhalt der Anfrage in Ruhe gelassen werden sollten:

var queryStringCollection = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);

    //example for param1
    string param1 = queryStringCollection["param1"];
    //example for param2
    int param2 = int.Parse(queryStringCollection["param2"]);
    //Example of getting the ID from the URL
    var id = actionContext.Request.RequestUri.Segments.LastOrDefault();
61
Mark Jones

Ich habe auf die Kontextroutendaten zugegriffen, um die Parameter aus einem benutzerdefinierten AuthorizeAttribute abzurufen, wenn Sie etwas wie /api/client/123/users aufrufen:

public class CustomAuthorizeAttribute : AuthorizeAttribute
  {
     protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
     {
        var clientId = Convert.ToInt32(actionContext.ControllerContext.RouteData.Values["clientid"]);

        // Check if user can access the client account.

     }
  }
22
simbolo

Sie können mit Ihrem benutzerdefinierten Berechtigungsattribut auf Abfragezeichenfolgenwerte zugreifen, indem Sie folgenden Code verwenden:

public class ApiAuthorizationFilter : AuthorizeAttribute
{
    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        var querystring = filterContext.RequestContext.HttpContext.Request.QueryString;
        // Do what you need
    }
}
1
jmberon

Obwohl diese Frage bereits beantwortet wurde. Falls jemand anderes es braucht, können Sie die Querystrings von ActionFilterAttribute wie folgt erhalten:

public class ApiAuthorizationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var queryParameters = actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);

        var some_value = queryParameters.ContainsKey("some_key")
                    ? queryParameters["some_key"] : string.Empty;

        // Log Action Filter call
        base.OnActionExecuting(actionContext);
    }
}

In der Regel werden für das Erstellen von API-Berechtigungen Header und eine benutzerdefinierte Überprüfungslogik verwendet, indem der Datenbank Schlüssel (eindeutige Zeichenfolgen) gegen Benutzer/Client usw. hinzugefügt werden.

public class ApiAuthorizationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var headers = actionContext.Request.Headers.ToDictionary(x => x.Key, x => x.Value);

        string api_key = headers.ContainsKey("api_key") ? headers["api_key"].FirstOrDefault() : null;

        bool canAccessApi = IsValidKey(api_key);

        if (!canAccessApi)
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You do not have access to this API. Please use a valid key.");

        // Log Action Filter call
        base.OnActionExecuting(actionContext);
    }

    private bool IsValidKey(string api_key)
    {
        //Build Access Control Logic here using database keys...
        return true;
    }
}
0
vohrahul