2017-08-09 4 views
0

Szenario ist Angularjs 1.6.5 App mit einem C# WebApi. Die Authentifizierung erfolgt gegen AAD unter Verwendung von angular-adal.js. Bis jetzt funktioniert alles perfekt, da sich Benutzer über AAD anmelden können und WebApi das Token akzeptiert.Angularjs Adal und weitere Ansprüche oder Eigenschaften für die Autorisierung

Für diese spezifische Anwendung befinden sich die Rollen in einer externen Anwendung, auf die der WebApi zugreifen kann. Ich habe in der Lage, die Rolle Ansprüche hinzuzufügen (nach sie aus der externen App holen) mit der Verwendung von WindowsAzureActiveDirectoryBearerAuthenticationOptions mit dem folgenden Code innerhalb der ConfigureOAuth(IAppBuilder app):

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions 
{ 
    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters 
    { 
     ValidAudience = clientId 
    }, 
    //Audience = ConfigurationManager.AppSettings["ida:ClientID"], 
    Tenant = tenant, 


    Provider = new OAuthBearerAuthenticationProvider 
    { 
     OnValidateIdentity = async context => 
    { 
     // Retrieve user JWT token from request. 
     var authorizationHeader = context.Request.Headers["Authorization"]; 
     var userJwtToken = authorizationHeader.Substring("Bearer ".Length).Trim(); 

     // Get current user identity from authentication ticket. 
     var authenticationTicket = context.Ticket; 
     var identity = authenticationTicket.Identity; 

     if (identity.FindFirst(System.Security.Claims.ClaimTypes.Role) == null) 
     { 
      var user = identity.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn").Value; 

      Cis.bll.Xrm.bllSystemUserRoles bllSystemUserRoles = new Cis.bll.Xrm.bllSystemUserRoles(); 
      var su = bllSystemUserRoles.getByEmail(user); 
      //var roleClaim = new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, su.stringRoles); 
      foreach (var item in su.Roles) 
      { 
       identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, item.xrmName)); 
      } 
     } 
    } 
    } 
}); 

Also für jeden httprequest dass AngularJS tut, um die API, die Die vorherige Funktion sucht die Rollen für den Benutzer und fügt die Rollenansprüche hinzu. Mit dieser Implementierung, kann ich eine AuthorizeAttribute in den Controller-Methoden verwenden, die Beschränkung des Zugriffs auf bestimmte Rollen wie so:

[CustomAuthorize(Constants.Roles.resourcesAdministrator)] 

Ich finde diese Art und Weise sehr inneficient, denn mit jeder httprequest, hat die API die holen Rollen des Benutzers aus der Datenbank (oder welcher Persistenzweg auch immer implementiert ist).

Was ich tun möchte, ist die Benutzerrollen nur einmal zu lesen, und dann in der Lage sein, sie bei jeder nachfolgenden Anfrage in der API zu verwenden. Gibt es eine Möglichkeit, die Ansprüche dem Token hinzuzufügen, nachdem wir das Token für AAD erhalten haben?

BTW, ich könnte nur hinzufügen, eine Rolle-Eigenschaft zu jedem Modell oder so etwas, aber es ist nicht das, was ich suche.

Wenn Sie andere Ideen oder Vorschläge haben, werden sie sehr geschätzt.

Grüße

+0

'angular'-Tag ist für' 2 + '' angularjs'-Tag ist für '1.x' – Kuncevic

+0

Dank für das Update @Kuncevic. Ich werde das im Hinterkopf behalten, da wir Angular 1.x verwenden. – aplon

Antwort

1

Das Token ist geändert nicht in der Lage, da es ausgegeben wird. Und da die Rollen in der anderen Anwendung gespeichert sind, glaube ich nicht, dass es möglich ist, die Rollen zu erhalten, ohne die Datenbank abzufragen.

In diesem Szenario können wir die Rollen über die Azure AD-Anwendungsrollen & Rollenansprüche verwalten. Dann wird es den roles Anspruch im id_token ausgeben.

Zum Beispiel können wir das Manifest der App wie unten ändern:

"appRoles": [ 
    { 
     "allowedMemberTypes": [ 
     "User" 
     ], 
     "displayName": "Writer", 
     "id": "d1c2ade8-98f8-45fd-aa4a-6d06b947c66f", 
     "isEnabled": true, 
     "description": "Writers Have the ability to create tasks.", 
     "value": "Writer" 
    }, 
    { 
     "allowedMemberTypes": [ 
     "User" 
     ], 
     "displayName": "Observer", 
     "id": "fcac0bdb-e45d-4cfc-9733-fbea156da358", 
     "isEnabled": true, 
     "description": "Observers only have the ability to view tasks and their statuses.", 
     "value": "Observer" 
    }, 
    { 
     "allowedMemberTypes": [ 
     "User" 
     ], 
     "displayName": "Approver", 
     "id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb", 
     "isEnabled": true, 
     "description": "Approvers have the ability to change the status of tasks.", 
     "value": "Approver" 
    }, 
    { 
     "allowedMemberTypes": [ 
     "User" 
     ], 
     "displayName": "Admin", 
     "id": "81e10148-16a8-432a-b86d-ef620c3e48ef", 
     "isEnabled": true, 
     "description": "Admins can manage roles and perform all task actions.", 
     "value": "Admin" 
    } 
    ], 

und weisen Sie die Rollen an den Benutzer durch die Anwendung über Azure-Portal wie Abbildung unten: enter image description here

wir dann kann die id_token-ähnliche Anfrage erhalten (implizite Zuteilungsfluss), die Rollen sollten im Token sein. Und wir können die Web-API mit diesem Token aufrufen.

Get:https://login.microsoftonline.com/{tenant}/oauth2/authorize?response_type=id_token&client_id={clientId}&redirect_uri={redirect_uri}&nonce={nonce} 

id_token Beispiel: enter image description here

+0

Danke für das Gespräch die Zeit zu beantworten Fei, also, ich sollte die Rollen von der externen Anwendung mit den AAD Roles synchronisieren. Auf diese Weise teilen sich beide Systeme die gleichen Rollen und ich würde die Rollen im Token bekommen. Recht? – aplon

+0

Ja, Sie hatten Recht. –

Verwandte Themen