0

Mit dem obigen Dienst mit Xamarin-Formular kann ich die Authentifizierung mit OAuth (Microsoft und Google) aktivieren. API-Aufruf funktioniert gut und diese Funktionen mit [Autorisieren], werden mit Authentifizierung erzwungen.Autorisierung der Azure Mobile App-Servicerolle funktioniert nicht

Wenn jedoch eine bestimmte Rolle definiert wird, wird 401 error zurückgegeben. Ich versuche, ein eigenes Attribut von AuthorizationFilterAttribute Klasse zu erstellen.

Ich bin Speichern der Benutzerinformationen und Rollen in meinem benutzerdefinierten Tabellen: Userprofile und Userroles. Daher bin ich mir nicht sicher, wo ich diese definieren soll. Da er keine Daten aus diesen Tabellen liest. Wenn ich versuche, folgendes auszuführen, gibt es ein leeres Ergebnis zurück.

[Authorize] 
    [HttpGet] 
    public IHttpActionResult Roles() 
    { 
     ClaimsIdentity claimsId = ClaimsPrincipal.Current.Identity as ClaimsIdentity; 
     var appRoles = new List<String>(); 
     foreach (Claim claim in ClaimsPrincipal.Current.FindAll(claimsId.RoleClaimType)) 
      appRoles.Add(claim.Value); 

     return Ok(appRoles); 
    } 

Der nächste Artikel, den ich über in auf Web API kam basiert: von Adrian Web Api 2 and Owin

bearbeiten Basierend auf Antwort, hinzugefügt folgende I-Code, aber noch denselben 401 Fehler.

public class MyAuthorize : System.Web.Http.Filters.AuthorizationFilterAttribute 
{ 
    private string[] accessRoleNames; 

    public MyAuthorize(params string[] roleNames) 
    { 
     accessRoleNames = roleNames; 
    } 

    public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken) 
    { 
     try 
     { 
      await Task.Delay(100); 
      OnAuthorization(actionContext); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 

    public override void OnAuthorization(HttpActionContext actionContext) 
    { 
     WMSEntities db = new WMSEntities(); 

     string userID = actionContext.ControllerContext.RequestContext.Principal.Identity.Name; 
     var user = db.UserProfiles.FirstOrDefault(x => x.User_ID == userID); 

     if (user == null) 
      actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); 
     else 
     { 
      bool ok = false; 
      foreach (var item in user.AppRoles) 
      { 
       foreach (string ar in accessRoleNames) 
       { 
        if (item.Name == ar) 
         ok = true; 
       } 
      } 
      db.Dispose(); 

      if (!ok) 
       actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); 
     } 
     base.OnAuthorization(actionContext); 
    } 
} 

Und zu meiner Funktion Referenzierung wie folgt:

[MyAuthorize(UserRole.Admin, UserRole.Collector)] 
    [HttpGet] 
    [Route("GetDataAdmin")] 
    public string GetDataAdmin() 
    { 
     return "success access GetDataAdmin"; 
    } 

Wenn ich den lokal Code debuggen, werden die OnAuthorization Ereignisse nicht getroffen werden, also nicht sicher, wie dies zu beheben.

Antwort

1

In Azure Mobile Apps verwenden Sie EntityFramework. Sie können alle gewünschten Abfragen durchführen. Hier ist ein Beispiel AuthorizationFilterAttribute die Ansprüche zurück durch einen AAD Berechtigungsnachweis überprüft:

using System.Linq; 
using System.Net; 
using System.Security.Principal; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.Http.Controllers; 
using System.Web.Http.Filters; 
using Microsoft.Azure.Mobile.Server.Authentication; 

namespace Backend.Helpers 
{ 
    public class AuthorizeClaimsAttribute : AuthorizationFilterAttribute 
    { 
     string Type { get; } 
     string Value { get; } 

     public AuthorizeClaimsAttribute(string type, string value) 
     { 
      Type = type; 
      Value = value; 
     } 

     public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken) 
     { 
      var request = actionContext.Request; 
      var user = actionContext.RequestContext.Principal; 
      if (user != null) 
      { 
       var identity = await user.GetAppServiceIdentityAsync<AzureActiveDirectoryCredentials>(request); 
       var countOfMatchingClaims = identity.UserClaims 
        .Where(c => c.Type.Equals(Type) && c.Value.Equals(Value)) 
        .Count(); 
       if (countOfMatchingClaims > 0) return; 

      } 
      throw new HttpResponseException(HttpStatusCode.Unauthorized); 
     } 
    } 
} 

Diese besondere Version, die Sie Dinge tun können wie:

[AuthorizeClaims("groups","some-object-id")] 

Sie können dies als Modell verwenden. Wo ich die GetAppServiceIdentityAsync() überprüfe, können Sie stattdessen Ihre Datenbank überprüfen und entscheiden, ob der Prinzipal eine Rolle hat.

+0

Ich versuchte oben, aber auch kein Glück. Immer noch 401 Fehler, und ich kann es nicht lokal debuggen, da das Ereignis nicht getroffen wird. –

+0

Einige Korrekturen in meinem Code und es funktioniert: var identity = actionContext.ControllerContext.RequestContext.Principal.Identity als ClaimsIdentity; Anspruch identityClaim = identity.Claims.FirstOrDefault (c => c.Type == ClaimTypes.NameIdentifier); var user = db.UserProfiles.FirstOrDefault (x => x.User_ID.EndsWith (identityClaim.Value)); ' –

Verwandte Themen