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() }); }
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); } }
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())); }