I am trying to check if the current user of a web app matches a particular one by doing this:
string t = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
when i console log this string i receive: UserOne
The problem i am running into is this:
if(t.Equals("UserOne"))
{
//this part does not fire off
}
else
{
//this part fires off
}
i don't understand. I'm clearly receiving the value of system.Security.Principal.WindowsIdentity.GetCurrent().Name; and as far as I can tell the if statement logic is correct.
Please help.
If you are running this in a console app, WindowsIdentity.Name will return your user name.
If you are running this in a ASPX site, WindowsIdentity.Name may return something completely different, e.g. the user name associated with the app pool in which your ASPX application is running.
For more information on this, check out this answer.
Related
I have created the registration and login form. Both work perfectly. But how do i recognize the user logged in as the PHP does by using SESSIONS and COOKIES. I can use static class to get data between different pages, but how can i retrieve the logged user data if he closes the application.
Is there any way for achieving this?
Thanks!
I'm assuming that you want something like instant messenger applications like Skype, or cloud storage applications like DropBox, OneDrive or Mega do. They ask you to enter user name and password once, and then start automatically without asking for user's credentials again.
They achieve this by storing user name and password in encrypted format in the file they normally keep in application folder under specific user account. See the following link for details: How can I get the current user directory?
This is standard practice, as another user will not be automatically logged into your app, if they not entered their own credentials.
Make sure you encrypt the user name and password or the whole file before saving it to disk, otherwise it may become an easy target for password stealing malware.
You should use user settings to do this, as this mechanism hides all the necessary work for creating files in the right locations, etc. from the developer. It works fine and it is made for stuff like this.
You design them in Visual Studio in the project properties on the "Settings" tab. Make sure to select the settings type correctly, as application settings are read-only.
Assume you have to settings UserName and UserPassword. Then, in your code, you could do this:
if (String.IsNullOrWhitespace(Properties.Settings.Default.UserName))
{
// USER NEEDS TO LOG IN
string userName;
string password;
if (Login(out userName, out password))
{
try
{
Properties.Settings.Default.UserName = Encrypt(userName);
Properties.Settings.Default.Password = Encrypt(password);
Properties.Settings.Default.Save();
}
catch (Exception exp)
{
...
}
}
}
else
{
// USER IS ALREADY LOGGED IN
}
private bool Login(out string userName, out string password) would be a method that shows a login user interface and returns true on success or false on failure.
private string Encrypt(string input) would be a method to encrypt a string.
I have one login page, user can use any machine while login into that page for the first time. once the user logged in for the first time, i need to restrict that user to not login into another machine. So user need to use only one machine that's used for the first time login.
I tried to get the client side mac address, but i can't able to get client side mac address in my website. Is there any other way to identity a machine uniquely?
For asp.net it's not possible to get the mac address of the client. You need to have some kind of windows application for that, that runs on the user's system.
A permanent cookie with a with a GUID might also be a solution.
Another solution might be to look up the servervariables when they make a request you will have Request.ServerVariables["REMOTE_ADDR"]; which would probably be the internal IP if the app is internal/intranet. There is also REMOTE_HOST. Sometimes these are filtered off by proxies/firewalls/nat but hopefully not in your situation.
Hope it helps!
if its intranet webapp, then you can enforce windows authentication - and keep a list of logged in users, in the database, with a timestamp of when the logged in user will automatically logout after the timestamp period.
Alternatively, use a cookie in forms authentication to do just that. But in any case, you will need the list of logged in users, and automatically log the user off, if he is on another machine.
More so, you can get the client's IP address and go from there, but its not reliable as it could be of an ISP. Its tricky, but cookies seems to be the simplest way of doing this.
However, a good solution would be to do it like IRC does, to keep track of logged in users. It sends a PING to the client, and expects the client to return a PONG, at different intervals of time. If the PONG is not received by the client, the IRC server automatically disconnects the user. Try this with something like SignalR. The downside of this is, if the user closes the browser and a PING request comes in, it will bounce back and the client will be disconnected as he/she will not be able to send a PONG request back.
I believe you want a user logged in on the website only in one session at any given time. Problem is that you can't know for sure when the user leaves, if he doesn't logout using the logout button.To fix this you have to have a timeout. I used a text file on the server in an application and it works.
Login button:
protected void btLogin_Click(object sender, EventArgs e)
{
if (check(txtPass.Text) && check(txtUser.Text))
{
var user = new UserManager().login(txtUser.Text, txtPass.Text);
if (user != null)
{
// this is the test you're looking for, the rest is only context
if (!FileManager.alreadyLoggedIn(user.email))
{
FormsAuthentication.SetAuthCookie(user.email, false);
}
else
{
//throw error that it is already connected in some other place
}
}
else
{
//throw error that login details are not OK
}
}
}
In a class two static methods:
//you have to call this function at every request a user makes
internal static void saveUserSessionID(string email)//email or any unique string to user
{
var dir = HostingEnvironment.MapPath("~/temp/UserSession/");// a folder you choose
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
string path = dir + email + ".txt";
File.WriteAllText(path, HttpContext.Current.Session.SessionID);
}
// if a request has not been made in tha last 4 minutes, the user left, closed the browser
// the test checks this only on a real server, localhost is not tested to be easy for the developer
internal static bool alreadyLoggedIn(string email)
{
var file = HostingEnvironment.MapPath("~/temp/UserSession/" + email + ".txt");
return File.Exists(file) && File.GetLastWriteTime(file).AddMinutes(4) > DateTime.Now && !HttpContext.Current.Request.IsLocal;
}
Obviously this is from another application, you can only take the idea and implement it in your own application. You can't just copy paste it.
The problem is that 1) Facebook seems so fluid with how it allows developers to interact with it (FBML, iFrame, different versions of SDKs) and 2) Everything I find is either PHP or Javascript and I have NO experience with those. What I am trying to do seems sooo simple, and I can't believe there isn't an easy way to do this.
What I have:
I used Visual Studio 2010 to create a simple web application (asp.net/C#) that asks the user for some info (first name, last name, email, etc.). I have a button on there called "Submit" that, when clicked, saves the entered data into a database. I have this hosted on GoDaddy (I know, I know...heh) and it works just fine. No problem here.
I created a "Facebook App" that uses the iFrame thingy so that basically I have a new tab on Facebook that displays my web app mentioned above. This works fine too. The tab is there, the web app is there, and users can enter the data and it is saved to the database. No problem here.
What I WANT:
I want the web app (the thing displayed by the facebook app) to only show the data entry part if the user currently "likes" the facebook entity. I DO NOT want to have to ask permission. I just want to know if they are a fan of the company's facebook "page" that has this app. So I need two things here, shown in my pseudo code below:
Part 1 (check if user is already a fan):
If (user is fan)
{
Show data entry area (unhide it)
}
else
{
Show "Click the like button to see more options"
}
Part 2 (listen for "like" event)
WhenLikeButtonPressed()
{
Show data entry area (unhide it)
}
I've seen stuff about "visible to connection", C# sdk, edge.create, etc. but I just can't make heads or tails of it. I don't mind putting in Javascript or PHP if someone could please give me exact, "Fan Gate for Dummies" steps. Please, I'm going crazy over here :-(
The key is is the signed_request that Facebook posts to your app when the user accesses the page. It contains the data on whether or not the user likes the page. You shouldn't need to worry about catching edge events on an actual tab FB page as it get's reloaded when the user likes/unlikes the page.
You'll need to decode the signed request with your app secret to get the like info. There are examples provided for PHP but I'm sure with a little google help you can find decode info for the signed_request for asp.net/c#.
Here's the php decode for reference:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
and the link https://developers.facebook.com/docs/authentication/signed_request/ the like info will be contained in the page variable
Description: i am user user1 (which is also the user of the app pool of sharepoint, so when i logon with user user1 it says welcome system account).
In my code, i want to test if a file is checked out by user 1, so the result of the following:
file.CheckedOutBy.LoginName.ToLower() == userName.ToLower())
is always false (which is not correct), CheckOutby value is (Sharepoint system) while username value is (user1).
How to resolve this?
Im using SP2010
You shouldn't use the user account which is used as a app pool account, because You will always see system account. In this case the best way is to change the app pool account to another which won't be used for another purposes.
Where does username come from?
Try this:
SPWeb web = SPContext.Current.Web; //get it from somewhere
if(file.CheckedOutBy == web.EnsureUser(username)) {
//do something
}
That should do the comparison on the SPUser.Id
Thanks all, this is how i solved it:
file.CheckedOutBy.LoginName.ToLower() == web.CurrentUser.LoginName.ToLower()
giving sharepoint\system on both sides, which was corrected.
I am editing a c# WinForm solution and I do not understand the code that gets the user account name. The code is shown below.
The application shows a customized form for each user account and the user account name is needed to get user-specific configuration values from an SQL database.
What happens, to the best I can tell, is the returned user name is correct for the first user account accessed, but after switching to a different user account, the returned user account name is not updated and the initial user account name continues to be returned.
#region "Function to retrieve LoggedIn user"
/// <summary>
/// "Function to retrieve LoggedIn user"
/// </summary>
/// <returns></returns>
private string GetLoggedInUserName()
{
ManagementClass objManClass = new ManagementClass("Win32_Process");
ManagementObjectCollection arrManObjects = objManClass.GetInstances();
foreach (ManagementObject objMan in arrManObjects)
{
if (objMan["Name"].ToString().Trim().ToLower() == "explorer.exe")
{
string[] arrArgs = { "", "" };
try
{
objMan.InvokeMethod("GetOwner", arrArgs);
sUserName = arrArgs[0];
break;
}
catch (Exception lExp)
{
BusinessObject.Logger.Logger.Log(lExp);
}
}
}
return sUserName;
}
#endregion
This application is to run on XP, Vista and 7.
My instinct is to just use something like...
string sUserName = Environment.UserName;
...but my knowledge of the Windows OS is poor and the people who wrote the original code are much smarter than me.
So my two questions are:
(1) Why does this code appear to not update to the new user name when I change user accounts?
(2) why use the 'explore.exe' method instead of simply using 'Environment.UserName'?
Also, two projects in my solution have a GetLoggedInUserName()method. One project runs in the background with a timer that calls the other project, and that project generates the user-customized form.
I have another related question about why the form fails to appear for all user accounts except the admin account that I will post as a separate question once I figure out this question.
If you want the currently logged in user, use can use the WindowsIdentity object:
string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
The Explorer process is always running when you log onto a Windows box, so it will always be found. If you open Task Manager and view the processes you will see it, and the account that started it. It looks like a throw back to VBScript, although I'm sure that there is an easier way to it with that too.
There is no good reason to use WMI to get the current user account on a local machine over other simpler methods.
For the user name bit try ...
string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;