如何最好地从Active Directory中检索用户数据以及SQL Server数据

时间:2017-10-10 19:24:04

标签: sql-server azure azure-active-directory azure-ad-b2c azure-ad-graph-api

我有一个Web应用程序,它将其数据存储在Azure SQL数据库中,以及有关Azure Active Directory B2C中经过身份验证的用户的数据。 SQL数据库中的数据与他们的" oid" (GUID)。这意味着获取数据库并不允许任何人识别特定用户。

但是,当我查询SQL数据以向访问者创建表格或图表时,我显然希望显示与拥有数据的用户相关的数据(即显示用户的全名,而不是他们的全名) OID!)。

我知道在网页上呈现SQL查询结果时我可以使用Azure Graph API来获取用户数据,但这似乎是一种非常低效的方法。除此之外,我不确定我是如何通过一批oid来传递所有用户对象而不使用可疑的长查询字符串过滤器!

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

我查看了Microsoft Graph API webhooks,但目前看来,我似乎没有关于用户对象更改的任何订阅,他们也不推荐使用B2C的Graph。

我想的另一个选择是在某处存储一个缓存来存储数据以便更快地查找,但这必须更新到。

感谢任何建议。

1 个答案:

答案 0 :(得分:1)

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

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

不要忘记将您的持有者令牌添加到授权标头:

Authorization: Bearer {accessToken}

此外,以下是您可能用于响应的对象示例(在Java中),其中包含一些有用的方法来检索注册电子邮件(假设您使用内置的B2C用户而不是第三方,例如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;
            }
        }
    }
}

如果您想提取多个用​​户,可以添加查询而不是“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