it-swarm.com.de

WEB API - Autorisierung auf Controller- oder Aktionsebene (keine Authentifizierung)

Ich habe eine vorhandene API, die über keine Authentifizierung verfügt. Hierbei handelt es sich um eine öffentliche Web-API, die von mehreren Clients verwendet wird, wenn einfache Anforderungen gestellt werden.

Nun muss der Zugriff auf eine bestimmte Methode autorisiert werden.

Gibt es eine Möglichkeit, dies zu tun, indem die restlichen Controller und die entsprechenden Methoden für die Clients "offen" bleiben, die diese Web-API bereits verwenden?

Wie kann ich feststellen, ob die Anforderung über Zugriffsberechtigungen für diese "geschützte" Methode verfügt?

8
JCruz

Sie müssen den Methoden, die Sie schützen möchten, ein [Authorize]-Attribut hinzufügen, wobei Sie optional die Überladung verwenden, die mindestens einen Rollennamen akzeptiert, in dem sich der aufrufende Benutzer befinden muss.

Dann müssen Sie implementieren, dass die Authentifizierungsdaten des Anrufers in ein Principal-Objekt umgewandelt werden. Das Festlegen des Principals ist im Allgemeinen etwas, das Sie nicht selbst tun, sondern stattdessen den Rahmen für Sie tun.

Wenn Sie eine eigene Schnittstelle bereitstellen möchten, können Sie einen Authentifizierungsfilter verwenden, der die System.Web.Http.Filters.IAuthenticationFilter-Schnittstelle implementiert. 

Was Sie also bekommen, ist folgendes:

[MyAuthentication]
[Authorize]
public SomeClass MyProtectedMethod() {
    return new SomeClass();
}

Und implementieren Sie dann das MyAuthentication-Attribut. Im Folgenden ist ein Beispiel dargestellt. Wichtig ist, dass Sie den Kontext der eingehenden Anforderung verwenden und die context.Principal-Eigenschaft mit einem neuen Principal festlegen

public class MyAuthentication : ActionFilterAttribute, System.Web.Http.Filters.IAuthenticationFilter {

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        // 1. Look for credentials in the request.
        HttpRequestMessage request = context.Request;
        AuthenticationHeaderValue authorization = request.Headers.Authorization;

        // 2. If there are no credentials, do nothing.
        if (authorization == null)
        {
            return;
        }

        // 3. If there are credentials but the filter does not recognize the 
        //    authentication scheme, do nothing.
        if (authorization.Scheme != "Basic")
        {
            return;
        }

        // 4. If there are credentials that the filter understands, try to validate them.
        // 5. If the credentials are bad, set the error result.
        if (String.IsNullOrEmpty(authorization.Parameter))
        {
            context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
            return;
        }

        Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);
        if (userNameAndPasword == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
        }

        string userName = userNameAndPasword.Item1;
        string password = userNameAndPasword.Item2;

        IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);
        if (principal == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
        }

        // 6. If the credentials are valid, set principal.
        else
        {
            context.Principal = principal;
        }

    }


    ... other interface methods here
}

Ich hoffe, das hilft Ihnen, auf die richtige Spur zu kommen. Weitere Informationen finden Sie in diesem Beitrag: http://www.asp.net/web-api/overview/security/authentication-filters

17
Robba

Sie können das [Authorize]-Attribut sowohl bei bestimmten API-Methoden als auch auf Controller-Ebene verwenden. Wenn Sie das [Authorize]-Attribut auf Controller-Ebene setzen, können Sie das [AllowAnonymous]-Attribut für die API-Methode verwenden, auf die Sie ohne Authentifizierung zugreifen möchten.

9
Rahul

Standardmäßig ist die Autorisierung in der Anwendung global deaktiviert. Sie können Ihren Controller zwingen, nur autorisierte Anfragen zuzulassen, indem Sie den Aktionsfilter [Authorize] hinzufügen.

[Authorize]  // This will enforce all methods inside should be authorized
public class AuthorizeController : ApiController
{
      //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }
}

Sie können auch erzwingen, dass bestimmte Methoden autorisiert werden:

public class AuthorizeController : ApiController
{
      [Authorize] //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }

      // This method can still be called even if user is not authorized
      public IHttpActionResult GetListUnauthorized()
      {
         return Ok();
      }
}

Oder deaktivieren Sie einfach die Autorisierung für einige Methoden in einem Controller, die eine Autorisierung erfordern:

[Authorize]
public class AuthorizeController : ApiController
{
      //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }

      [AllowAnonymous]// This method can be called even if user is not authorized due the AllowAnonymous attribute
      public IHttpActionResult GetListUnauthorized()
      {
         return Ok();
      }
}

Sie können auch festlegen, wer auf Ihre Methode zugreifen darf:

[Authorize(Users="Joey,Billy")]

Oder nach Regeln mit:

[Authorize(Roles="Administrator,Manager")]

Oder erstellen Sie sogar ein komplexeres Berechtigungsattribut wie in dieser Antwort (basierend auf Ansprüchen): Berechtigungsattribut nach Ansprüchen

3
Rafael A. M. S.

Wir haben es mit [AllowAnonymous] für die Methode gelöst, die nicht authentifiziert werden wollte, sondern autorisiert wurde und die Autorisierung überschreibt.

0
Ruben Lopez