pur*_*uri 3 asp.net-identity azure-active-directory openid-connect azure-ad-graph-api asp.net-core
此处显示的代码是我尝试在 ASP.NET Core 2.0 中针对我的 Azure AD 租户执行身份验证。
有趣的部分是我收到身份验证代码后的下一组目标。
我想将经过身份验证的用户的 AD 组放入声明中,并将它们传递给我的基于策略的授权注册。
为了实现这一点,我交换了访问令牌的授权代码。
获得访问令牌后,我使用 Microsoft Graph SDK 来检索经过身份验证的用户的 AD 组。
问题 1:我见过访问令牌存储在缓存中的示例IDistributedCache。为什么这很重要,不执行此步骤有什么风险,究竟是AdalDistributedTokenCache什么?
例如
var cache = new AdalDistributedTokenCache(distributedCache, userId);
var authContext = new AuthenticationContext(ctx.Options.Authority, cache);
Run Code Online (Sandbox Code Playgroud)
我发现访问令牌总是通过
string accessToken = await HttpContext.GetTokenAsync("access_token");
Run Code Online (Sandbox Code Playgroud)
问题 2:检索组后,如果我将这些作为声明添加到 Principal 中,那么我是否可以使用它们来驱动此处所述的授权策略?
问题 3:访问令牌和 id 令牌以及我添加的声明最终会出现在 cookie 中吗?
问题 4:如何强制 Azure AD 将 AD 角色作为声明返回(而不是组,因为我可以通过 Graph 获取这些角色)而不必更改某种清单?
完整代码
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
Configuration.GetSection("OpenIdConnect").Bind(options);
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = async ctx =>
{
// Exchange authorization code for access token
var request = ctx.HttpContext.Request;
var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);
var authContext = new AuthenticationContext(ctx.Options.Authority);
var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
ctx.ProtocolMessage.Code, new Uri(currentUri), credential, ctx.Options.Resource);
// Use Microsoft Graph SDK to retrieve AD Groups
var email = ctx.Principal.Claims.First(f => f.Type == ClaimTypes.Upn).Value;
GraphServiceClient client = new GraphServiceClient(
new DelegateAuthenticationProvider(
async requestMessage => {
var accessToken = result.AccessToken;
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
}));
var groups = await client.Users[email].GetMemberGroups(false).Request()
.PostAsync();
// Do something with groups
ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
};
});
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizePage("/Index");
});
}
Run Code Online (Sandbox Code Playgroud)
问题 1:我见过访问令牌存储在缓存中的示例
IDistributedCache。为什么这很重要,不执行此步骤有什么风险,究竟是AdalDistributedTokenCache什么?
默认情况下,ADAL 使用内存中的令牌缓存,用于保存它获取的访问和刷新令牌。通过使用由 Redis 等支持的分布式缓存,所有托管应用程序的实例都可以访问令牌缓存。如果应用程序在负载均衡器后面运行,这是必需的,并且还可以防止应用程序重新启动时丢失数据。
问题 2:检索组后,如果我将这些作为声明添加到 Principal 中,那么我是否可以使用它们来驱动此处所述的授权策略?
您可以在用户主体上添加新身份,类似于我的文章:https : //joonasw.net/view/adding-custom-claims-aspnet-core-2。如果您在处理程序中添加身份,它应该可以工作OnAuthorizationCodeReceived。它们将使用默认登录方案(在您的情况下为 Cookies)存储为声明。所以是的,你可以在政策中使用它们。
问题 3:访问令牌和 id 令牌以及我添加的声明最终会出现在 cookie 中吗?
是的,它们都保存在 cookie 中。但是,您应该在需要时使用 ADAL 来获取访问令牌。只要您正确设置 ADAL 令牌缓存,您的情况就不需要保存令牌的选项。
获取令牌:https : //github.com/juunas11/aspnetcore2aadauth/blob/master/Core2AadAuth/Startup.cs#L75
使用令牌:https : //github.com/juunas11/aspnetcore2aadauth/blob/master/Core2AadAuth/Controllers/HomeController.cs#L89
示例应用程序首先为登录用户创建令牌缓存。然后,我们使用 ADAL 的AcquireTokenSilentAsync方法静默获取访问令牌。这意味着 ADAL 将返回缓存的访问令牌,或者如果它已过期,则使用缓存的刷新令牌来获取新的访问令牌。如果这两个都失败,则抛出异常。在示例应用程序的情况下,有一个异常过滤器可以捕获异常并将用户重定向到登录:https : //github.com/juunas11/aspnetcore2aadauth/blob/master/Core2AadAuth/Filters/AdalTokenAcquisitionExceptionFilter.cs
问题 4:如何强制 Azure AD 将 AD 角色作为声明返回(而不是组,因为我可以通过 Graph 获取这些角色)而不必更改某种清单?
如果你的意思是像Global Administrator这样的角色,你就不能在声明中得到它。您在应用清单中定义并分配给用户/组的角色始终包含在令牌中。https://joonasw.net/view/defining-permissions-and-roles-in-aad
| 归档时间: |
|
| 查看次数: |
1185 次 |
| 最近记录: |