1

Ich habe eine Webanwendung, die ihre Daten in einer Azure SQL-Datenbank speichert und Daten über authentifizierte Benutzer in Azure Active Directory B2C. Daten in der SQL-Datenbank beziehen sich auf AD-Benutzer über ihre "oid" (GUID). Dies bedeutet, dass durch das Abrufen der Datenbank niemand bestimmte Benutzer identifizieren kann.Wie kann ich am besten Benutzerdaten aus Active Directory in Verbindung mit SQL Server-Daten abrufen?

Wenn ich jedoch die SQL-Daten abfrage, um einem Besucher eine Tabelle oder ein Diagramm zu erstellen, möchte ich die Daten natürlich in Beziehung zu dem Benutzer anzeigen, der die Daten besitzt (dh den vollständigen Namen des Benutzers anzeigen, nicht die oid!) .

Ich weiß, dass ich die Azure Graph API verwenden kann, um Benutzerdaten zu erhalten, wenn die Ergebnisse der SQL-Abfrage auf einer Webseite gerendert werden, aber dies scheint eine sehr ineffiziente Art und Weise zu tun. Hinzu kommt, dass ich nicht sicher bin, wie ich einen Stapel von OIDs übergeben würde, um alle Benutzerobjekte zurück zu bekommen, ohne einen lächerlich langen Abfrage-String-Filter zu verwenden!

Ich könnte eine Art von Synchronisierungsprozess erstellen, der die gesamte AD) abfragt und eine SQL-Tabelle in einem zeitgesteuerten Prozess (vielleicht eine Azure-Funktion) aktualisiert, aber das scheint auch schrecklich ineffizient?

Ich schaute auf Microsoft Graph API-Webhooks, aber im Moment scheint es keine Subskription zu geben, die ich in Bezug auf Benutzerobjektänderungen aufnehmen kann und sie empfehlen Graph mit B2C nicht.

Die andere Option, die ich denke, wäre, irgendwo einen Cache zu haben, der die Daten für schnelleres Nachschlagen speichert, aber dieses würde aktualisiert werden müssen.

Alle Vorschläge dankbar geschätzt.

Antwort

1

Es ist eigentlich ziemlich einfach (vorausgesetzt, Sie sind bereits authentifiziert). Verwenden Sie diese als Vorlage für die GET-Anfrage:

{baseUrl}/{tenantId}/users/{oid}?api-version={api-version} 

Vergessen Sie nicht, Ihre Inhaber Token an den Authorization-Header hinzuzufügen:

Authorization: Bearer {accessToken} 

Auch hier ist ein Beispiel für ein Objekt, das Sie verwenden können für die Antwort (in Java), einige hilfreiche Methoden für die Anmeldung E-Mail-Abruf (vorausgesetzt, Sie in B2C-Benutzer erstellt werden anstelle von dritten, wie google):

import com.fasterxml.jackson.annotation.JsonIgnore; 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 
import com.fasterxml.jackson.annotation.JsonProperty; 

import java.util.ArrayList; 
import java.util.List; 

@JsonIgnoreProperties(ignoreUnknown = true) 
public class GraphApiUserExample{ 

    @JsonProperty("objectId") 
    private String id; 

    private Boolean accountEnabled; 

    private com.brmic.azure.graph.api.client.model.PasswordProfile PasswordProfile; 

    private List<SignInName> signInNames; 

    private String surname; 

    private String displayName; 

    private String givenName; 

    @JsonProperty("userPrincipalName") 
    private String userPrincipalName; 

    public String getId(){ 

     return id; 
    } 

    public void setId(final String id){ 

     this.id = id; 
    } 

    public Boolean getAccountEnabled(){ 

     return accountEnabled; 
    } 

    public void setAccountEnabled(final Boolean accountEnabled){ 

     this.accountEnabled = accountEnabled; 
    } 

    public com.brmic.azure.graph.api.client.model.PasswordProfile getPasswordProfile(){ 

     return PasswordProfile; 
    } 

    public void setPasswordProfile(final com.brmic.azure.graph.api.client.model.PasswordProfile passwordProfile){ 

     PasswordProfile = passwordProfile; 
    } 

    public List<SignInName> getSignInNames(){ 

     return signInNames; 
    } 

    public void setSignInNames(final List<SignInName> signInNames){ 

     this.signInNames = signInNames; 
    } 

    public String getSurname(){ 

     return surname; 
    } 

    public void setSurname(final String surname){ 

     this.surname = surname; 
    } 

    public String getDisplayName(){ 

     return displayName; 
    } 

    public void setDisplayName(final String displayName){ 

     this.displayName = displayName; 
    } 

    public String getGivenName(){ 

     return givenName; 
    } 

    public void setGivenName(final String givenName){ 

     this.givenName = givenName; 
    } 

    public String getUserPrincipalName(){ 

     return userPrincipalName; 
    } 

    public void setUserPrincipalName(final String userPrincipalName){ 

     this.userPrincipalName = userPrincipalName; 
    } 

    @JsonIgnore 
    public String getSignInEmail(){ 

     String email = ""; 
     if(signInNames != null){ 
      for(SignInName signInName : signInNames){ 
       if(signInName.getType().equals("emailAddress")){ 
        email = signInName.getValue(); 
        break; 
       } 
      } 
     } 
     return email; 
    } 

    @JsonIgnore 
    public void setSignInEmail(String signInEmail){ 

     if(signInNames == null){ 
      signInNames = new ArrayList<>(); 
      signInNames.add(new SignInName("emailAddress", signInEmail)); 
      return; 
     } 

     for(SignInName signInName : signInNames){ 
      if(signInName.getType().equals("emailAddress")){ 
       signInName.setValue(signInEmail); 
       break; 
      } 
     } 
    } 
} 

Wenn Sie pu wollen Wenn Sie mehrere Benutzer haben, können Sie eine Abfrage anstelle der 'oid' hinzufügen, um die Ergebnisse zu filtern und durchzublättern.

{baseUrl}/{tenantId}/users?api-version={api-version}&$skiptoken={skiptoken}&$top={top}&$filter={attributeOne} eq '{valueOne}' 
{baseUrl}/{tenantId}/users?api-version={api-version}&$skiptoken={skiptoken}&$top={top}$filter=signInNames/any(x:x/value eq '{email}') 

dem ein JSON-Objekt wie folgt zurückgibt:

{ 
    "users":[...], 
    "odata":{ 
     "nextLink": "{baseUrl}/{tenantId}/users?api-version={api-version}&$skiptoken={skiptoken}&$top={top}&$filter={attributeOne} eq '{valueOne}'" 
     "metadata": "I forget if this is just a string or a parsable JSON object." 
    } 

} 

Sie werden nach wie vor das Problem, haben die Ergebnisse der Abfrage an Ihre DB Treffer, die eine schwere Operation sein wird. Ich empfehle, dass Sie die Ergebnisse in einer Tabelle für Joins zwischenspeichern, wenn Sie schnellere Operationen ausführen müssen. Es fühlt sich klugdy an, aber nur weil es ist. Es gibt auch einige Powershell-Befehle aus dem B2C azure-Powershell-Modul, die Sie verwenden könnten, und Sie können ADAL verwenden, um einen Job in SQL Server zum Aktualisieren des Inhalts Ihrer Tabelle oder Sicht zu erstellen.

Dokumentation ist hier: https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet

+0

Vielen Dank für Ihren Vorschlag Pytry - Ich habe Code bereits, die die API pro Zeile nennen kann die authentifizierte GET Anfrage mit jedem oid verwenden. Mein Punkt ist, dass ich dies einmal pro Zeile in der resultierenden Ausgabe auf der Webseite tun müsste. Das fühlt sich furchtbar ineffizient an, also suchte ich nach Möglichkeiten, dies zu mildern - auf irgendeine Weise, einen Haufen Oids auf einmal zu vertreiben? – RNDThoughts

+0

Das endete so, wie ich es gemacht habe, aber ich fühle mich nicht ganz richtig. – RNDThoughts

+0

Es tut uns leid, dass wir nicht bald wieder bei Ihnen waren (war beschäftigt). Sie können auch eine Abfrage hinzufügen, um mehrere Benutzer gleichzeitig abzurufen, und dann zusätzliche Filter/Validierung ausführen, um sie mit Daten von SQL Server abzugleichen. Um die Schwere dieser Art von Operation geht es nicht; Wenn Sie einen schnellen Zugriff auf die Ergebnisse benötigen, dann sollten Sie sich mit Caching beschäftigen. Gimme ein bisschen (hoffentlich heute), um meine Antwort zu aktualisieren, um mehrere Ergebnisabfragen einzuschließen. – Pytry

Verwandte Themen