public async Task <FindClaimsResponse> Execute(FindClaimsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (request.Aliases == null)
            {
                throw new ArgumentNullException(nameof(request.Aliases));
            }

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var criterion = new AliasesCriterion {
                Aliases = request.Aliases
            };
            var profiles = await Provider.Search(criterion);

            var build = new Func <IdentityData, Claim[]>(p =>
            {
                var claims = new List <Claim>();
                claims.Add("userName", p.AliasName);
                claims.Add("userLabel", p.FullName);
                claims.Add("aliasName", p.AliasName);
                claims.Add("firstName", p.FirstName);
                claims.Add("lastName", p.LastName);
                claims.Add("fullName", p.FullName);

                return(claims.ToArray());
            });
            var results = from profile in profiles
                          select new ResultModel
            {
                Alias  = profile.AliasName,
                Claims = build(profile),
            };

            stopwatch.Stop();

            return(new FindClaimsResponse
            {
                Meta = new
                {
                    Duration = stopwatch.ToDuration()
                },
                Results = results.ToArray()
            });
        }
예제 #2
0
        public async Task <UserData> ProvisionUser(string provider, string userId, string connectId, List <Claim> claims)
        {
            var criterion = new AliasesCriterion
            {
                Aliases = new[]
                {
                    userId,
                    connectId,
                }
            };
            var profiles = await Provider.Search(criterion);

            if (profiles.Any())
            {
                var userClaims = new List <Claim>();

                var identity = profiles.SingleOrDefault(p => p.AliasName.Equals(userId, StringComparison.InvariantCultureIgnoreCase));
                if (identity == null)
                {
                    userClaims.Add("userName", userId);
                    userClaims.Add("userLabel", "anonymous");
                    userClaims.Add("aliasName", connectId);
                    userClaims.Add("firstName", "anonymous");
                    userClaims.Add("lastName", "anonymous");
                    userClaims.Add("fullName", "anonymous");
                }
                else
                {
                    var principal = profiles.SingleOrDefault(p => p.AliasName.Equals(connectId, StringComparison.InvariantCultureIgnoreCase));
                    if (principal == null)
                    {
                        principal = identity;
                    }

                    userClaims.Add("userName", identity.AliasName);
                    userClaims.Add("userLabel", identity.FullName);

                    userClaims.Add("aliasName", principal.AliasName);
                    userClaims.Add("firstName", principal.FirstName);
                    userClaims.Add("lastName", principal.LastName);
                    userClaims.Add("fullName", principal.FullName);
                }

                var query = from entry in Cache
                            where entry.Provider == provider &&
                            entry.ExternalId == userId
                            select entry;

                var user = query.FirstOrDefault();
                if (user == null)
                {
                    user = new UserData
                    {
                        SubjectId  = userId,
                        ConnectId  = connectId,
                        Username   = userId,
                        Provider   = provider,
                        ExternalId = userId,
                        Claims     = userClaims,
                    };
                }
                else
                {
                    user.ConnectId = connectId;
                    user.Claims    = userClaims;
                }

                Cache.Add(user);
                return(user);
            }
            else
            {
                var nameSchema = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
                var nameClaim  = claims.Find(p => p.Type == "name" || p.Type == nameSchema);
                var name       = nameClaim == null
                    ? userId
                    : nameClaim.Value;

                var user = new UserData
                {
                    SubjectId  = userId,
                    Username   = name,
                    Provider   = provider,
                    ExternalId = userId,
                    Claims     = claims,
                };

                Cache.Add(user);
                return(user);
            }
        }
예제 #3
0
        public Task <IdentityData[]> Search(AliasesCriterion criterion)
        {
            if (criterion == null)
            {
                throw new GuardException("The criterion cannot be null");
            }
            if (criterion.Aliases == null)
            {
                throw new GuardException("The criterion names cannot be null");
            }
            if (criterion.Aliases.Empty())
            {
                throw new GuardException("The criterion names cannot be empty");
            }

            // ToDo: Encapsulate setup at construction level [DanD]

            // Setup
            var identity = WindowsIdentity.GetCurrent();
            var user     = identity.User;

            if (user == null)
            {
                throw new Exception("The user could not be retrieved from identity");
            }

            var context   = new PrincipalContext(ContextType.Domain);
            var principal = UserPrincipal.FindByIdentity(context, IdentityType.Sid, user.Value);

            if (principal == null)
            {
                throw new Exception("The principal could not be retrieved from identity");
            }

            var node = principal.GetUnderlyingObject() as DirectoryEntry;

            if (node == null)
            {
                throw new Exception("The underlying object for principal is not a directory entry");
            }

            while (node.SchemaClassName != "domainDNS")
            {
                node = node.Parent;
            }

            // Search
            var names = from name in criterion.Aliases
                        where !string.IsNullOrEmpty(name)
                        select $"(name={name})";
            var filter = $"(|{names.Collate()})";

            var attributes = new[]
            {
                "cn",
                "sn",
                "name",
                "givenname",
                "displayname",
                "mail",
                "company",
                "department",
                "description",
                "memberof",
                "department",
                "extensionattribute9",
                "extensionattribute10",
                "extensionattribute11",
                "physicaldeliveryofficename",
                "msexchuserculture",
                "physicaldeliveryofficename",
                "telephonenumber",
                "homedirectory",
            };

            var searcher = new DirectorySearcher(node, filter, attributes)
            {
                SearchScope = SearchScope.Subtree,
                Sort        = new SortOption("cn", SortDirection.Ascending),
            };
            var results = searcher.FindAll();

            // Projection
            var profiles = from result in results.OfType <SearchResult>()
                           select new IdentityData
            {
                AliasName        = result.Parse <string>("cn"),
                FirstName        = result.Parse <string>("givenname"),
                LastName         = result.Parse <string>("sn"),
                FullName         = result.Parse <string>("displayname"),
                EmailAddress     = result.Parse <string>("mail"),
                PhoneNumber      = result.Parse <string>("telephonenumber"),
                CompanyName      = result.Parse <string>("company"),
                OrganizationPath = result.Parse <string>("extensionattribute11"),
                DepartmentName   = result.Parse <string>("department"),
                FunctionName     = result.Parse <string>("extensionattribute9"),
                OfficeName       = result.Parse <string>("physicaldeliveryofficename"),
                ContractType     = result.Parse <string>("description"),
                CultureCode      = result.Parse <string>("msexchuserculture"),
                PicturePath      = result.Parse <string>("extensionattribute10"),
            };

            return(Task.FromResult(profiles.ToArray()));
        }