在 ASP.NET Core 2.0 中使用 OpenID Connect 时,AdalDistributedTokenCache 是什么?

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 中,那么我是否可以使用它们来驱动此处所述的授权策略?

ASP.NET Core 中基于策略的授权

问题 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)

juu*_*nas 5

问题 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