如何以最佳方式从Active Directory中检索用户数据以及SQL Server数据
我有一个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。
另一种选择,我想将有一个缓存某处存储的数据更快的查找,但这将不得不更新到。
任何建议感激地赞赏。
实际上它非常简单(假设您已经过身份验证)。以此为模板的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中创建一个用于更新表或视图内容的作业。
谢谢您的建议Pytry - 我已经有代码,可以调用使用GET认证与每个OID要求每行的API。我的观点是,我需要在网页的输出结果中每行执行一次。这感觉非常低效,所以我一直在寻找缓解这种方式的方法 - 一次性传递一堆oid的方式? – RNDThoughts
这最终成为我与之一起的方式,但感觉不太正确。 – RNDThoughts
很抱歉没有及时回复(忙)。您还可以添加一个查询以同时获取多个用户,然后运行其他筛选器/验证以使其与来自SQL Server的数据相匹配。没有人知道这种操作的沉重感。如果你需要快速访问结果,然后开始寻找缓存。给我一点(希望今天)更新我的答案,包括多个结果查询。 – Pytry