在 MVC 中存储身份验证数据
Store authentification data in MVC
我创建了一个自定义授权属性,我在其中使用 Office Graph 获取当前用户所属的 AAD 组,并根据这些我拒绝或授权用户。我想保存组,因为调用 Office Graph 需要一些性能。保存此类数据的正确方法是什么?我可以看到有些人将它保存到 SQL 服务器,但我需要确保清理等
我还可以在某些线程中看到,由于并发性,会话状态被认为是一个错误的选择。所以问题是你有什么选择来存储这种信息?
欢迎所有建议。
如果您只使用 group_id 信息,则根本不需要使用 Office Graph 和存储它。我们可以通过更改 Azure AD 的清单来启用 Azure AD 发出组声明:(参考 this code sample)
"groupMembershipClaims": "All",
如果您还使用有关群组的其他信息,您可以将这些信息存储到声明中。以下是将组名添加到声明中的代码示例,供您参考:
AuthorizationCodeReceived = async context =>
{
ClientCredential credential = new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst(Globals.ObjectIdClaimType).Value;
AuthenticationContext authContext = new AuthenticationContext(ConfigHelper.Authority, new TokenDbCache(userObjectId));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigHelper.GraphResourceId);
ActiveDirectoryClient graphClient = new ActiveDirectoryClient(new Uri(ConfigHelper.GraphServiceRoot),
async () => { return await Task.FromResult(result.AccessToken); }
);
try
{
foreach (var groupClaim in context.AuthenticationTicket.Identity.FindAll("groups"))
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri($"https://graph.windows.net/adfei.onmicrosoft.com/groups/{groupClaim.Value}?api-version=1.6"),
Method = HttpMethod.Get,
};
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage httpResponse = httpClient.SendAsync(request).Result;
var retJSON = httpResponse.Content.ReadAsStringAsync().Result;
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(retJSON);
((ClaimsIdentity)context.AuthenticationTicket.Identity).AddClaim(new Claim("groupName", dict["displayName"].ToString()));
}
}
}
catch (Exception ex)
{
}
},
然后我们可以使用以下代码从控制器获取这些信息:
ClaimsPrincipal.Current.FindAll("groupName")
我创建了一个自定义授权属性,我在其中使用 Office Graph 获取当前用户所属的 AAD 组,并根据这些我拒绝或授权用户。我想保存组,因为调用 Office Graph 需要一些性能。保存此类数据的正确方法是什么?我可以看到有些人将它保存到 SQL 服务器,但我需要确保清理等
我还可以在某些线程中看到,由于并发性,会话状态被认为是一个错误的选择。所以问题是你有什么选择来存储这种信息?
欢迎所有建议。
如果您只使用 group_id 信息,则根本不需要使用 Office Graph 和存储它。我们可以通过更改 Azure AD 的清单来启用 Azure AD 发出组声明:(参考 this code sample)
"groupMembershipClaims": "All",
如果您还使用有关群组的其他信息,您可以将这些信息存储到声明中。以下是将组名添加到声明中的代码示例,供您参考:
AuthorizationCodeReceived = async context =>
{
ClientCredential credential = new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst(Globals.ObjectIdClaimType).Value;
AuthenticationContext authContext = new AuthenticationContext(ConfigHelper.Authority, new TokenDbCache(userObjectId));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigHelper.GraphResourceId);
ActiveDirectoryClient graphClient = new ActiveDirectoryClient(new Uri(ConfigHelper.GraphServiceRoot),
async () => { return await Task.FromResult(result.AccessToken); }
);
try
{
foreach (var groupClaim in context.AuthenticationTicket.Identity.FindAll("groups"))
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri($"https://graph.windows.net/adfei.onmicrosoft.com/groups/{groupClaim.Value}?api-version=1.6"),
Method = HttpMethod.Get,
};
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage httpResponse = httpClient.SendAsync(request).Result;
var retJSON = httpResponse.Content.ReadAsStringAsync().Result;
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(retJSON);
((ClaimsIdentity)context.AuthenticationTicket.Identity).AddClaim(new Claim("groupName", dict["displayName"].ToString()));
}
}
}
catch (Exception ex)
{
}
},
然后我们可以使用以下代码从控制器获取这些信息:
ClaimsPrincipal.Current.FindAll("groupName")