I have a simple C# login system (Winform application). I have a separated class (ActiveUser) to store user details when they're logging in.
In ActiveUser class, I have a variable called loggedInUserID.
So, when the user logs in, on the login form, I set a value to that variable.
ActiveUser obj = new ActiveUser();
obj.setLoggedUserID(UserID);
Now I have a CheckLoggedIn() method in each form that checks whether the user is logged in or not. So, that I can block users from accessing unauthorized pages.
So, how to check that ? If I did like this, it's just another object.
CheckLoggedIn(){
ActiveUser obj = new ActiveUser();
if(obj.getLoggedUserID() != 0){
MessageBox.Show("Logged In");
}
}
So, how to check the object value I create when the user logging in ?
I think the Singleton Pattern is the most suitable in this situation.
Let's make ActiveUser a simple singleton class.
In the ActiveUser class, add something like this:
public static readonly ActiveUser User = new ActiveUser();
To SetLoggedUserID, just do:
ActiveUser.User.SetLoggedUser(...);
And you can check it like this:
void CheckLoggedIn(){
if(ActiveUser.User.getLoggedUserID() != 0){
MessageBox.Show("Logged In");
}
}
To avoid accidentally creating a new instance of ActiveUser, I recommend you to make the constructor private:
private ActiveUser() { ... }
Related
I have a Web Forms application that does not have a login page. Technically a user can access any page directly. However, I need to be able to identify who the logged-in user is on each page. I don't want to add code to each page. I would rather set a unique session variable at the start of the session. For this I added into my Global.asax.cs the following:
protected void Session_Start(object sender, EventArgs e)
{
if (Session["LoggedInUser"] == null)
{
string networkId = HttpContext.Current.User.Identity.Name;
using (UnitOfWork unit = new UnitOfWork())
{
if (networkId.IndexOf("HLM\\") > -1) { networkId = networkId.Substring(4, networkId.Length - 4); }
loggedInUser = unit.PersonRepository.GetByNetworkID(networkId);
Session["LoggedInUser"] = loggedInUser;
}
}
else
{
loggedInUser = (Person)Session["LoggedInUser"];
}
}
I now see that it sets the loggedInUser to whatever user last created a session. Meaning, if Mike goes to the site he will see data that represents him as the loggedInUser. However, if Kate goes to the site after him, Mike will now see Kate's data. Basically, the last one in overwrites everyone's settings and Session_Start is overwriting the value for loggedInUser for all active Sessions.
Based on this link: https://books.google.com/books?id=nQkyi4i0te0C&pg=PA202&lpg=PA202&dq=C%23+set+unique+session+variable+in+global.asax&source=bl&ots=GV9nlEUzE5&sig=E4TT3NDbjp1GwEehgU3pLXKdvr0&hl=en&sa=X&ved=0ahUKEwiU9f322tvSAhVF7yYKHYaXCtwQ6AEITzAI#v=onepage&q=C%23%20set%20unique%20session%20variable%20in%20global.asax&f=false
It reads that I should be able to set unique session variables for each new session but my results don't show that.
Am I misunderstanding how this works? I need to set a unique session value at the beginning of each session for each user.
I found the issue. The Session_Start is doing what is supposed to at a unique session level. The way I was referencing the session value was all wrong. Instead of accessing the session value I was actually doing:
Person loggedInUser = Global.loggedInUser;
Which makes sense that it was returning the latest user to start a session.
I'm developing a WebForms web application with VS2010 in C#. I use my custom login approach to authenticate users and I don't want to use Membership framework. After user login I want to store user data as userId, username, surname, email, etc., so I can access them during the user session in all pages.
How can I do that? I don't wanna store user data in the UserData property of the FormsAuthenticationTicket.
I found this approach: Should I store user data in session or use a custom profile provider?, but I don't understand how to implement it.
I have some question:
1)in my login page to authenticate user after check credentials on db I use : FormsAuthentication.SetAuthCookie(txtUserName.Value, true); now in my default page I have:
FormsAuthenticationTicket ticket = ((FormsIdentity)(User.Identity)).Ticket; and I use ticket.Name to show username. is it correct? why do you talk about thread using Thread.CurrentPrincipal.Identity.Name ?
2) I have this code in global.asax file to read user roles and store thems into HttpContext:
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated) {
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnStr"].ConnectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT Gruppi.Name FROM Ruoli INNER JOIN Gruppi ON Ruoli.GroupID = Gruppi.GroupID INNER JOIN Utenti ON Ruoli.UserID = Utenti.UserID AND Utenti.Username=#UserName", conn);
cmd.Parameters.AddWithValue("#UserName", User.Identity.Name);
SqlDataReader reader = cmd.ExecuteReader();
ArrayList rolelist = new ArrayList();
while (reader.Read()){
rolelist.Add(reader["Name"]);
}
// roleList.Add(reader("Name"))
string[] roleListArray = (string[])rolelist.ToArray(typeof(string));
HttpContext.Current.User = new GenericPrincipal(User.Identity, roleListArray);
reader.Close();
conn.Close();
}
}
can I store user data into session as you wrote from my global.asax file rather then login.aspx page?
In the interest of easier debugging, I suggest using the Session Facade design pattern, described here, that will allow you to store the current user's data using the HttpContext.Current.Session object in a more organized fashion.
For instance, there would be a file (e.g., SessionFacade.cs) that is responsible for handling the values passed to/from the Session; in your case, it might look like:
public static class SessionFacade
{
public static int UserId
{
get {
if (HttpContext.Current.Session["UserId"] == null)
HttpContext.Current.Session["UserId"] = 0;
return (int)HttpContext.Current.Session["UserId"];
}
set {
HttpContext.Current.Session["UserId"] = value;
}
}
// ... and so on for your other variables
}
Then, somewhere else in your code, once you check that credentials are okay, you can do...
if (credentialsAreOk) {
SessionFacade.UserId = /* insert ID here */
// ...
}
...instead of manually assigning values to the Session object. This ensures your variables in Session are of the correct type, and will be easier to track while debugging. Then, to get the UserId from anywhere in your program, it's just SessionFacade.UserId.
(yes that snippet was from Eduard's answer; you should still look into that answer as it is informative as to how WebForms work; just keep in mind that calling the Session object manually in your code can be quite messy and that the Session Facade makes that process cleaner)
In case that by "web application by VS2010 in C#" you're talking about ASP.NET (MVC or Classic) and by "custom login approach" you're referring to FormsAuthentication then all you need to do is to store your later needed information at login time, onto the Session object.
Let's say you're using ASP.NET Classic and you have a login page
which has 2 inputs for Username and Password and a submit button entitled "Login"
In the button's (server side) OnClick event handler you should do something like this:
public partial class Login : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
}
private bool CheckUserPass(string username, string password) {
// access DB or some other form of storage service
return true;
}
protected void buttonLogin_Click(object sender, EventArgs e) {
bool credentialsAreOk = this.CheckUserPass(
this.textBoxUsername.Text,
this.textBoxPassword.Text
);
if (credentialsAreOk) {
this.Session["EMAIL_ADDRESS"] = "SomeEmail#SomeEmailProvider.com";
this.Session["OTHER_INFORMATION_KEY"] = "Some other stuff which you have access to during the login process";
this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;
FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);
}
}
}
So, in short, if you're using FormsAuthentication, then the username can be stored onto the session in the same way you're telling the FormsAuthentication system that current session should be transformed from non-authenticated to authenticated:
FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);
whereas other information can be placed on the Session object (just like you would add key value pairs to a Dictionary):
this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;
While it is obvious how you could later access that same information (for the respective user):
DateTime whenDidILogin = (DateTime) this.Session["TIME_OF_LOGIN"];
// this line of code can be used in any other page
// at any later time - it's like you have a global set of variables
// which exist for each and every distinct session you might have
it is maybe important to mention that the username (if not placed explicitly onto the Session object like the other examples) can be accessed by means of the Thread.CurrentPrincipal static property like so:
using System.Threading;
public void SomeWhereInYourApp() {
bool wasIAuthenticated = Thread.CurrentPrincipal.Identity.IsAuthenticated;
string whatIsMyUsername = Thread.CurrentPrincipal.Identity.Name;
// do something with that information
}
Membership provider helps you to store data and also for authentication purpose. Something like this:-
Session["UserName"] = Membership.GetUser().UserName
i have developing project in c# for creating a user in AD.
i create a user and i want to create a attribute,like "mobilenumber"for this user.
when,i create this,the below error will occured.
here my code.
if (userDetails.GetUnderlyingObjectType() == typeof(DirectoryEntry))
{
dEntry = (DirectoryEntry)userDetails.GetUnderlyingObject();
if (User.UsrPassword != null && User.UsrPassword.Trim() != "")
{
if (dEntry.Properties.Contains("mobilenumber"))
{
Console.WriteLine("mobilenumberAttribute:Already created");
dEntry.Properties["mobilenumber"][0] = User.UsrPassword;
dEntry.CommitChanges();
}
else
{
Console.WriteLine("mobilenumber Attribute: Adding");
dEntry.Properties["mobilenumber"].Add(User.UsrPassword);
dEntry.CommitChanges();
}
userDetails.Save();
result = true;
}
}
The requested operation did not satisfy one or more constraints associated with the class of the object. (Exception from HRESULT: 0x80072014)
How can i resolve this?
Create an attribute? You mean like extending the schema? You can't do that by just adding it to an object. As you can see here, there is no such attribute as "mobilenumber". Maybe you want otherMobile (Phone-Mobile-Other) or mobile (Phone-Mobile-Primary)?
What are you trying to do? Why keep a copy of the password in the user object. If the user changes it, your copy will not be updated. If you need it to somehow inform the user, do something different like infoming his supervisor... Just a thought.
I have a field named username as the session variable. I have added a class which inherits the base page. Now I want the code to get the session variable in all the pages that the user moves through.
Please help me with the code.
You should be able to access the Session variable form all pages in the following way:
var username = Session["Username"].ToString();
Hope this helps
You can access your current session variables using the Session object with an index, like
var myvalue = Session["mysessionvariable"];
Use session["username"] to get the value. Then use this value as per your need
You can add a property in a base class (which is inherited from Page class) which will encapsulate the Session variable and inherit that base class in every page you create
public string UserNameInSession
{
get
{
return HttpContextCurrent["UserNameSessionKey"].ToString();
}
set
{
HttpContextCurrent["UserNameSessionKey"] = value;
}
}
And then you can use this property either to set or get the Username from/to session like
string UserName = UserNameInSession; //Get it
UserNameInSession = string.Empty();//set it
I have designed several Client/Server applications. I am working on a project that involves a user logging in to gain access to the application. I am looking at the most efficient and "simple" method of storing the users permissions once logged in to the application which can be used throughout restricting access to certain tabs on the main form.
I have created a static class called "User" detailed below:
static class User
{
public static int _userID;
public static string _moduleName;
public static string _userName;
public static object[] UserData(object[] _dataRow)
{
_userID = (int)_dataRow[0];
_userName = (string)_dataRow[1];
_moduleName = (string)_dataRow[2];
return _moduleName;
}
}
When the user logs in and they have been authenticated, I wish to store the _moduleName objects in memory so I can control which tabs on the main form tab control they can access, for example; if the user has been assigned the following roles in the database: "Sales Ledger", "Purchase Ledger" they can only see the relevant tabs on the form, by way of using a Switch - Case block once the login form is hidden and the main form is instantiated. I can store the userID and userName variables in the main form once it loads by means of say for example:
Here we process the login data from the user:
DataAccess _dal = new DataAccess();
switch (_dal.ValidateLogin(txtUserName.Text, txtPassword.Text))
{
case DataAccess.ValidationCode.ConnectionFailed:
MessageBox.Show("Database Server Connection Failed!");
break;
case DataAccess.ValidationCode .LoginFailed:
MessageBox.Show("Login Failed!");
_dal.RecordLogin(out errMsg, txtUserName.Text, workstationID, false);
break;
case DataAccess.ValidationCode .LoginSucceeded:
frmMain frmMain = new frmMain();
_dal.GetUserPrivList(out errMsg,2); //< here I access my DB and get the user permissions based on the current login.
frmMain.Show();
this.Hide();
break;
default:
break;
}
private void frmMain_Load(object sender, EventArgs e)
{
int UserID = User._userID;
}
That works fine, however the _modules object contains mutiple permissions/roles depending on what has been set in the database, how can I store the multiple values and access them via a Switch-Case block?
If I am understanding properly, you want to be able to store permissions/roles as a value in a database per user.
I believe you can write an integer to a database field like : RolesID. Write to you database field the value of the flag. Something like:
[Flag]
public enum ROLES
{
Administrator = 1,
User = 2,
OtherRole3 = 4,
OtherRole4 = 8
}
You should be able to read that value in and assign to a field declared as:
ROLES userRoles = GetRoleValueFromDB();
I'm pretty certain I've done this before.
HTH...