Example #1
0
        public async Task <ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            //transform can run more than once.
            //the service is scoped, so setting and testing the Principal property allows short-circuiting
            if (ScopePrincipal != null)
            {
                return(ScopePrincipal);
            }
            ScopePrincipal = principal;

            //if there is no oid, then principal didn't come from AzureAD / OpenIdConnect
            if (principal.GetObjectId() == null)
            {
                return(principal);
            }

            var claimsIdentity = principal.Identities.First();

            //mark principal with claim for this transform
            claimsIdentity.AddClaim(new Claim("transform", GetType()?.FullName ?? "AzureGroupsClaimsTransform"));

            var claimsCacheResult = await Cache.GetGroupClaimsAsync(principal);

            var groupNames = claimsCacheResult.Value;

            if (!claimsCacheResult.Success)
            {
                var accessToken = await TokenAcquisition.GetAccessTokenForAppAsync(Options.GraphEndpoint, authenticationScheme : Options.Scheme);

                try
                {
                    groupNames = (await GraphService.GroupsAsync(principal, accessToken))?.Select(x => x.DisplayName);
                }
                catch (Exception e)
                {
                    var requestId = Activity.Current?.Id ?? "<null>";
                    Logger.LogCritical(e, "AzureGroupsClaimsTransform exception from RequestId: {requestId}.", requestId);

                    claimsIdentity.AddClaim(new Claim("transform-error", e.Message));
                    claimsIdentity.AddClaim(new Claim("transform-error-request-id", requestId));

                    return(principal);
                }
                if (groupNames != null)
                {
                    await Cache.SetGroupClaimsAsync(principal, groupNames, Options.DistributedCacheEntryOptions);
                }
            }

            foreach (var group in groupNames !)
            {
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, group, ClaimValueTypes.String, "AzureAD"));
            }

            return(principal);
        }