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
You have defined one in your own code
You are using the default ASPNET Membership Provider which has a
GetNumberOfUsersOnline()
method defined.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
Import and Export Excel - What Is the Best Library
MVC Razor View Nested Foreach's Model
Multiple Types Were Found That Match the Controller Named 'Home'
How to Handle Dependency Injection in a Wpf/Mvvm Application
How to Fix the Microsoft Visual Studio Error: "Package Did Not Load Correctly"
Dynamically Adding Properties to an Expandoobject
How to Get Current User, and How to Use User Class in MVC5
How to Install a Windows Service Programmatically in C#
.Net - What's the Best Way to Implement a "Catch All Exceptions Handler"
Memory Allocation: Stack VS Heap
The Name 'Configurationmanager' Does Not Exist in the Current Context
Sorting a List Using Lambda/Linq to Objects
C# Image Resizing to Different Size While Preserving Aspect Ratio