How to Retrieve a List of Logged-In/Connected Users in .Net

How do you retrieve a list of logged-in/connected users in .NET?

Here's my take on the issue:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace EnumerateRDUsers
{
class Program
{
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] string pServerName);

[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);

[DllImport("wtsapi32.dll")]
static extern Int32 WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] Int32 Reserved,
[MarshalAs(UnmanagedType.U4)] Int32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);

[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);

[DllImport("wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(
IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);

[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;

[MarshalAs(UnmanagedType.LPStr)]
public string pWinStationName;

public WTS_CONNECTSTATE_CLASS State;
}

public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}

public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}

static void Main(string[] args)
{
ListUsers(Environment.MachineName);
}

public static void ListUsers(string serverName)
{
IntPtr serverHandle = IntPtr.Zero;
List<string> resultList = new List<string>();
serverHandle = WTSOpenServer(serverName);

try
{
IntPtr sessionInfoPtr = IntPtr.Zero;
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
Int32 sessionCount = 0;
Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref sessionInfoPtr, ref sessionCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
IntPtr currentSession = sessionInfoPtr;
uint bytes = 0;

if (retVal != 0)
{
for (int i = 0; i < sessionCount; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
currentSession += dataSize;

WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);

Console.WriteLine("Domain and User: " + Marshal.PtrToStringAnsi(domainPtr) + "\\" + Marshal.PtrToStringAnsi(userPtr));

WTSFreeMemory(userPtr);
WTSFreeMemory(domainPtr);
}

WTSFreeMemory(sessionInfoPtr);
}
}
finally
{
WTSCloseServer(serverHandle);
}

}

}
}

Getting a list of logged-in users in ASP.NET Identity

There is no built in support for this. One simple way you could implement this would be to add a LastActivityDate to your user, which is updated whenever a user does something on your site. Then you can just query against that looking for users who are active within some reasonable time, like 30 minutes and display that.

How to Get a List of Logged in Users?

I'm a Developer Advocate at Auth0. Let me see if I can help you out :).

The whole idea of having an API that just checks the JWT is to have a Stateless API. Being "logged in" doesn't really exist in concept. All JWTs expire at some point in time, and that's what checked when you call an API.

Therefore, what I suggest is the following:

Every time you get an API call you save the JWT somewhere on memory. Then, we need to get logged in users, you just grab all the JWTs that you have on those list, and show the not expired ones as "logged in". Also, you should have a cron that goes every 5 minutes over the list and which cleans expires JWTs. It's not really "logged in" users, but I think it's close enough.

Would that work?

Thanks

ASP.NET | Forms Authentication | Get ALL logged in users(list of all users or count)

No there isn't unless

  1. You have defined one in your own code

  2. You are using the default ASPNET Membership Provider which has a GetNumberOfUsersOnline() method defined.

  3. You are using a custom Membership Provider and have provided an implementation for the GetNumberOfUsersOnline() method yourself

The default ASPNET Membership provider calculates number of users online by querying the SQL Server database and checking the LastActivityDate stored against each user against the defined UserIsOnlineTimeWindow property that you can set in web.config. If the LastActivityDate is greater than the current time minus the UserIsOnlineTimeWindow value (which represents minutes), then a user is considered to be online.

If you wanted to do something similar then you might consider implementing a similar method. you can see the code for the default providers by downloading the source code. To complete your picture, you might also want to run aspnet_regsql.exe so that you can see the stored procedures that the default providers use.

Get current logged in username from Active Directory?

If you're on .NET 4.5 or higher, just use the System.DirectoryServices.AccountManagement namespace and the UserPrincipal class in that context:

// you'll need to add a reference to this .NET assembly in your project
// so that you can use this namespace
using System.DirectoryServices.AccountManagement;

public string GetLoggedInUser()
{
// establish the PrincipalContext - this will grab the default domain, default containers
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// get the currently active user
UserPrincipal currentUser = UserPrincipal.Current;

if (currentUser != null)
{
// this will return "first name last name" separated by a space,
// e.g. "John Doe" or "Jane Tarzan"
return $"{currentUser.GivenName} {currentUser.Surname}";
}
}

return string.Empty;
}

How to query currently logged in user's AD information in MVC 4

Since you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:

  • Managing Directory Security Principals in the .NET Framework 3.5
  • MSDN docs on System.DirectoryServices.AccountManagement

Basically, you can define a domain context and easily find users and/or groups in AD:

// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");

if(user != null)
{
// do something here....
string homeDrive = user.HomeDrive;
string homeDirectory = user.HomeDirectory;
}
}

If you're using Windows Authentication in your ASP.NET MVC app, you could also fetch the currently logged in user like this:

UserPrincipal currentUser = UserPrincipal.Current;

But more often than not, in a web app, this is something like NETWORK SERVICE or the IUSER_machineName user (and not your user at the browser)...

The new S.DS.AM makes it really easy to play around with users and groups in AD!

how to get logged on users with their status on remote machine

You can use the Win32_LogonSession WMI class filtering for the LogonType property with the value 2 (Interactive)

Try this sample

using System;
using System.Collections.Generic;
using System.Management;
using System.Text;

namespace GetWMI_Info
{
class Program
{

static void Main(string[] args)
{
try
{
string ComputerName = "remote-machine";
ManagementScope Scope;

if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "username";
Conn.Password = "password";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);

Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=2");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);

foreach (ManagementObject WmiObject in Searcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "LogonId", WmiObject["LogonId"]);// String
ObjectQuery LQuery = new ObjectQuery("Associators of {Win32_LogonSession.LogonId=" + WmiObject["LogonId"] + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
ManagementObjectSearcher LSearcher = new ManagementObjectSearcher(Scope, LQuery);
foreach (ManagementObject LWmiObject in LSearcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "Name", LWmiObject["Name"]);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}", e.Message, e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}


Related Topics



Leave a reply



Submit