1

我有一个Web应用程序,它将数据存储在Azure SQL数据库中以及有关Azure Active Directory B2C中经过身份验证的用户的数据。 SQL数据库中的数据通过其“oid”(GUID)与AD用户相关联。这意味着获取数据库不允许任何人识别特定的用户。但是,当我查询SQL数据为访问者创建表或图表时,我显然希望显示与拥有数据的用户相关的数据(即显示用户的全名,而不是他们的oid!) 。如何以最佳方式从Active Directory中检索用户数据以及SQL Server数据

我知道在网页上呈现SQL查询结果时,我可以使用Azure Graph API来获取用户数据,但这似乎是一种非常低效的方法。添加到其中,我不知道如何通过一批oid来获取所有用户对象,而无需使用可观的长查询字符串过滤器!

我可以创建一种查询整个AD的同步过程) 并更新定时过程(可能是Azure功能)上的SQL表,但这似乎也是非常低效的?

我看了一下Microsoft Graph API webhooks,但目前似乎没有任何订阅可以与用户对象更改挂钩,他们不建议使用B2C的Graph。

另一种选择,我想将有一个缓存某处存储的数据更快的查找,但这将不得不更新到。

任何建议感激地赞赏。

回答

1

实际上它非常简单(假设您已经过身份验证)。以此为模板的GET请求:

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

不要忘了你的承载令牌添加到Authorization头:

Authorization: Bearer {accessToken} 

而且,这里是一个对象,你可以使用的一个例子为响应(在Java中),与检索注册电子邮件一些有用的方法(假设你使用内置的B2C用户,而不是第三方,如谷歌):

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; 
      } 
     } 
    } 
} 

如果你想PU如果有多个用户,您可以添加一个查询,而不是“oid”来过滤并遍历结果。

{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}') 

它返回一个JSON对象是这样的:

{ 
    "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." 
    } 

} 

您仍然有查询的结果匹配您的数据库结果,这将是一项繁重的操作的问题。 如果你需要运行更快的操作,我建议你使用缓存结果在表中进行连接。 它确实感到kludgey,但只是因为它。

还有一些可以使用的B2C azure powershell模块的powershell命令,您可以使用ADAL在SQL Server中创建一个用于更新表或视图内容的作业。

文档是在这里:https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet

+0

谢谢您的建议Pytry - 我已经有代码,可以调用使用GET认证与每个OID要求每行的API。我的观点是,我需要在网页的输出结果中每行执行一次。这感觉非常低效,所以我一直在寻找缓解这种方式的方法 - 一次性传递一堆oid的方式? – RNDThoughts

+0

这最终成为我与之一起的方式,但感觉不太正确。 – RNDThoughts

+0

很抱歉没有及时回复(忙)。您还可以添加一个查询以同时获取多个用户,然后运行其他筛选器/验证以使其与来自SQL Server的数据相匹配。没有人知道这种操作的沉重感。如果你需要快速访问结果,然后开始寻找缓存。给我一点(希望今天)更新我的答案,包括多个结果查询。 – Pytry

相关问题