I am fetching application from active directory. Total number of applications are increased and now they are above 999. Maximum number of items in one page can be 999. I want to fetch all applications in one page collection.
I am using following code to fetch applications, but it seems that there is no method in activedirectory client to return all apps in one call.
Can I make collection of pages and append all pages using do while?
IPagedCollection<IApplication> applications = null;
applications = await activeDirectoryClient.Applications.Take(999).ExecuteAsync()
You can try to get all the applications like this:
List<IApplication> applicationList = new List<IApplication>();
IPagedCollection<IApplication> pagedCollection = activeDirectoryClient.Applications.ExecuteAsync().Result;
do
{
applicationList.AddRange(pagedCollection.CurrentPage.ToList());
pagedCollection = pagedCollection.GetNextPageAsync().Result;
} while (pagedCollection != null && pagedCollection.MorePagesAvailable);
Related
For my application, when a user login, I display a prompt and ask if the user wants to save the password to keychain. The code saves successfully and I'm able to query the keychain for the stored password completely fine.
My question is how come when I check my phone under Passwords & Acccounts - Website & App Passwords, nothing is displayed.
The bit of code I used to save the key
public static bool SaveValueToKeyChain(string entryKey, string entryValue)
{
SecRecord record = new SecRecord(SecKind.GenericPassword)
{
Account = entryKey,
Label = entryKey,
Service = _keyChainServiceName
};
SecStatusCode resultCode;
SecKeyChain.QueryAsRecord(record, out resultCode);
if (resultCode == SecStatusCode.Success)
{
if (SecKeyChain.Remove(record) != SecStatusCode.Success)
{
return false;
}
}
resultCode = SecKeyChain.Add(new SecRecord(SecKind.GenericPassword)
{
Label = entryKey,
Account = entryKey,
Service = _keyChainServiceName,
Accessible = SecAccessible.WhenUnlockedThisDeviceOnly,
Synchronizable = true,
ValueData = NSData.FromString(entryValue, NSStringEncoding.UTF8),
});
return resultCode == SecStatusCode.Success;
}
I've also followed the solution from here https://developer.xamarin.com/samples/monotouch/Keychain/ and no luck as well. May I get some assistance.
For each application, the keychain has two access zones, a private zone and a public zone (that is, a group mode).
Private area :is a closed storage area. Each application can only operate its own private area. Any data stored in this application is invisible to other programs, and other programs do not have permission to access this private area. (Can be understood as a sandbox with a keychain).
Public area: apple provides a data sharing module between multiple apps developed by the same developer account. It is now limited to data sharing between different apps under the same developer account. This area is another data storage space that is independent of the private area. Achieve common access to some data between multiple applications.
I guess here should be the private area.You can have a try with group mode. Sharing Access to Keychain Items Among a Collection of Apps
How can I get my app to open the last edited file after a click in the Windows 10 Timeline? Thanks for the help.
var activityId = Guid.NewGuid().ToString();
UserActivityChannel channel = UserActivityChannel.GetDefault();
UserActivity userActivity = await channel.GetOrCreateUserActivityAsync(activityId);
userActivity.VisualElements.DisplayText = PageTitle.Text;
if (File != null)
{
userActivity.VisualElements.Description = File.DisplayName;
}
userActivity.VisualElements.BackgroundColor = Colors.Black;
userActivity.VisualElements.Content = AdaptiveCardBuilder.CreateAdaptiveCardFromJson(cardText);
userActivity.ActivationUri = new Uri("my-app:navigate?page=" + _index);
await userActivity.SaveAsync();
_currentActivity?.Dispose();
_currentActivity = userActivity.CreateSession();
From the UserActivityChannel Class, there is a GetRecentUserActivitiesAsync method, but it only get the specified number of the most recently engaged user activities sorted by the time each user activity ended. Due to the privacy protecting policy of UWP app, your app can not get the user activities from system or other apps.
Currently, in your app, you can only operate the user activities which your app created. If the file is edited by the system or other app, you can not implement the effect you want. But if the file is operated by your app, you can try to create a user activity which is for opening the file then handle the protocol activated event in your app to open it. Maybe you should see the topic track recently used files.
I have added the ClientBuildManager.PrecompileApplicaiton to my Azure web role as described here. The web role will start, however, takes an extraordinary long time (15-20 mins), presumably from the amount of files it has to compile (18K+).
After the role starts, I hit the site, which doesn't appear to be any faster in initial startup.
When I RDP to my web role, I can see 2 separate folders in the Temporary ASP.NET Files, one containing all of my pre-compiled code (3K+ files), the other containing a smaller set of files matching those that would be used during my initial request (50 files).
From what I can tell, the site is pre-compiling, however, the actual requests are not leveraging this pre-compilation and doing a normal on-the-fly compilation as before when a request is made.
After viewing the above, I made another request to a different page within my site and confirmed the folder with 50 files increased to 58 files, telling me it is in fact still doing on-the-fly compiling. The other folder with 3K files remained unchanged.
Here is the code I am using for my pre-compilation in my OnStart method:
var siteName = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
var mainSite = serverManager.Sites[siteName];
var rootVirtualPath = String.Format("/LM/W3SVC/{0}/ROOT/", mainSite.Id);
var clientBuildManager = new ClientBuildManager(rootVirtualPath, null);
clientBuildManager.PrecompileApplication();
Am I missing something else that would force the role to use my pre-compiled files?
Here's the full code that works, note one important difference is to NOT include trailing slash in appVirtualDir
using (var serverManager = new ServerManager())
{
string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_" + "Web";
var siteId = serverManager.Sites[siteName].Id;
var appVirtualDir = $"/LM/W3SVC/{siteId}/ROOT"; // Do not end this with a trailing /
var clientBuildManager = new ClientBuildManager(appVirtualDir, null, null,
new ClientBuildManagerParameter
{
PrecompilationFlags = PrecompilationFlags.Default,
});
clientBuildManager.PrecompileApplication();
}
For quite a few days now I have been trying to get some custom Active Directory based authentication to work. It all works in theory but apparently my theory is wrong. Users who are logged on to a domain write a string token (e.g. PIN code) to their own property field in Active Directory (doesn't really matter which one, but I used primaryInternationISDNNumber for this) upon logging on to the ASP.NET application This PIN is always generated and written programmatically.
To explain it roughly, the web browser loads a Java applet which then loads a native DLL written in C++, which generates and writes the PIN to current user's Active Directory field. That DLL then returns the generated PIN to the applet which then passes it to the browser, which performs an AJAX call with the data returned to initiate the authentication. The application, which has got access to the AD, reads this field value for the connecting user object and checks if it matches with the one the user supplied. If PIN codes match, the user is successfully authenticated.
This is the sample code the ASP.NET application used to read the AD:
using (var de = new DirectoryEntry("LDAP://" + domainName))
{
using (var adSearch = new DirectorySearcher(de))
{
// Get user from active directory.
adSearch.Filter = "(sAMAccountName=" + userName.Trim().ToLower(CultureInfo.CurrentCulture) + ")";
var adSearchResult = adSearch.FindOne();
var entry = adSearchResult.GetDirectoryEntry();
var pinCodeProp = entry.Properties["primaryInternationISDNNumber"];
return pinCodeProp != null ? pinCodeProp.Value : string.Empty;
}
}
This works fine, often. But often is not acceptable. It needs to always be working.
The trouble is that the ASP.NET application sometimes gets the value which was previously in that field, not the actual value. As if there is some kind of caching. I have tried to add de.UsePropertyCache = false but that yielded the same results.
I have created two Win32 console applications for test purposes. One writes the PIN code, the other reads the PIN code. They always work fine!
I thought, this gotta be some problem with IIS application pool. So I have created a native DLL which gets loaded by the ASP.NET application using Platform Invoke. This DLL creates a new thread, calls CoInitialize and reads the PIN code. This is the code:
pszFqdn = argv[1];
pszUserName = argv[2];
pszPassword = argv[3];
IADs *pObject = NULL;
HRESULT hr = S_OK;
hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = ADsOpenObject(pszFqdn, pszUserName, pszPassword, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID*)&pObject);
if (SUCCEEDED(hr) && pObject)
{
VARIANT var;
VariantInit(&var);
hr = pObject->Get(CComBSTR("primaryInternationalISDNNumber"), &var);
if ((SUCCEEDED(hr) && var.bstrVal) || hr == 0x8000500d)
{
if (hr != 0x8000500d)
{
// convert the BSTR received to TCHAR array
std::wstring wsValue(var.bstrVal, SysStringLen(var.bstrVal));
// copy the received value to somewhere
// ... not relevant
}
VariantClear(&var);
}
pObject->Release();
}
}
CoUninitialize();
To my tremendous and unpleasant surprise, this code after a day of working properly, started returning the previous values, just like the managed code before!
So now I thought, alright, I wasn't able to escape the IIS application pool and since this gotta be a problem with IIS application pool, I will create a native Windows application which I will execute by using Process.Start method. I will return my PIN code by means of process exit code (since it's an integer anyway). The application uses the similar C++ code as the DLL above.
So I start my application, wait for it to finish, read the exit code. Returns the bad value!
But okay, I'd say, the process is started using the current user credentials, which is again IIS application pool. So I start the application under different credentials. And guess what..... it returns the old value again (?!?!?!).
And I thought Java was hell... Anyone has got any idea about what could possibly be going on here?
It was the replication indeed. As I didn't want to force the replication before reading the field (that would have been a time-expensive operation probably anyway), I came to an idea to read this field from each domain controller and check if any of them matches with the value supplied.
As it might prove helpful to someone, I did that using the following code.
var ctx = new DirectoryContext(
DirectoryContextType.DirectoryServer,
ipAddress,
userName, // in the form DOMAIN\UserName or else it would fail for a remote directory server
password);
var domain = Domain.GetDomain(ctx);
var values = new List<string>();
foreach (DomainController dc in domain.DomainControllers)
{
using (var entry =
new DirectoryEntry(
"LDAP://" + dc.IPAddress,
userName,
password))
{
using (var search = new DirectorySearcher(entry))
{
search.Filter = "(&(primaryInternationalISDNNumber=*)(sAMaccountName=" + userName + "))";
var result = search.FindOne();
var de = result.GetDirectoryEntry();
if (de.Properties["primaryInternationalISDNNumber"].Value != null)
{
values.Add(de.Properties["primaryInternationalISDNNumber"].Value.ToString());
}
}
}
}
I am using C# in VS2008 in a WinXP/Win7/WinServer2003 environment.
Is there a way to search the active directory without involving LDAP?
I have users created in Active Directory but when I search using this
DirectorySearcher dirSearcher = new DirectorySearcher(
new DirectoryEntry("LDAP://DC=kmmnet,DC=com"),
"(objectClass=user)",
new string[] { "sAMAccountName", "displayname", "givenname", "sn" });
foreach (SearchResult s in dirSearcher.FindAll())
{
System.DirectoryServices.PropertyCollection p = s.GetDirectoryEntry().Properties;
}
it cannot find some of the users.
thanks
Shawn
Try bumping the PageSize attribute up from its default of zero:
dirSearcher.PageSize = 9000;
Any non-zero value for PageSize will cause paging to occur, so that you will receive all results (in batches equal to the PageSize).
You can also try filtering the search more (e.g., exclude inactive users, etc.).
And, there is an upper limit on the number of results which a directory server will return in response to an LDAP query. This limit is controlled and set by an administrator on the domain. I believe the default is 1000.