I want to check if a user is logged in and if they are, deny them access to the registration and login pages. When a user logs in I'm setting these session variables:
HttpContext.Current.Session["LoggedIn"] = true;
HttpContext.Current.Session["FullName"] = (string)Reader["FirstName"] + " " + (string)Reader["LastName"];
Response.Redirect("Default.aspx");
And I'm checking them at the top of the register and login pages like so:
if ((bool)HttpContext.Current.Session["LoggedIn"])
{
Response.Redirect("Default.aspx");
}
However, when I try to go to the page while not logged in this exception gets thrown:
Object reference not set to an instance of an object.
I'm assuming it's ebcause the LoggedIn key doesn't exist because I only create it after a successful login.
So, how can I check if the LoggedIn key exists and if it doesn't, redirect the user to Default.aspx?
Thanks!
I think you can do a simple null check on this like....
if (HttpContext.Current.Session["LoggedIn"] != null)
{
// once inside this loop
// you can now read the value from Session["LoggedIn"]
Response.Redirect("Default.aspx");
}
you need to make shure that the object is not null before unboxing it
if(HttpContext.Current.Session["LoggedIn"]!=null)
{
if ((bool)HttpContext.Current.Session["LoggedIn"])
{
Response.Redirect("Default.aspx");
}
}
Why to avoid the default webforms authentication model altogether? Simply use web.config to define a restricted area, set all the settings correctly and you won't have to perform checks like this for every page.
But, if you want to reinvent the wheel....
You check for something that probably doesn't exist yet. You must modify your if-statement like this:
bool isLoggedIn = (HttpContext.Current.Session["LoggedIn"] == null ? false : (bool)HttpContenxt.Current.Session["LoggedIn"];
if (isLoggedIn)
{
Response.Redirect("Default.aspx");
}
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 attempting to check if a given user has access to a specific Custom Table.
Based on the example listed on the kentico documentation to check permissions for a custom table, I have setup a similar call, using my custom table class name and userinfo, but the call to "UserInfoProvider.IsAuthorizedPerClass" always return false:
private bool CheckCustomTableReadPermission(UserInfo user = null)
{
// Gets the user object
//UserInfo user = UserInfoProvider.GetUserInfo("CMSEditor");
//UserInfo user = UserInfoProvider.GetUserInfo("someothervalidusername");
//UserInfo user = CurrentUser;
//normally outside of this function
UserInfo CurrentUser = MembershipContext.AuthenticatedUser;
string CustomTableClassName = "Namespc.TblName";
if (user == null)
{
user = CurrentUser;
}
if (user != null)
{
// Checks whether the user has the Read permission for the CMS.MenuItem page type
if (UserInfoProvider.IsAuthorizedPerClass(CustomTableClassName, "Read", SiteContext.CurrentSiteName, user))
{
// Perform an action according to the result
return true;
}
}
return false;
}
Can anyone also mention what the valid permission name strings are, other than "Read"? (e.g.: "Modify"? "Delete"? "Insert"?)
Does UserInfoProvider.IsAuthorizedPerClass resolve all memberships of the given user, or does it only check if the user is explicitly added to the Custom Table?
Any suggestions? We're using Kentico v8.2.25
Thanks!
Victor
What about doing it the same way as it's done in
CMS\CMSModules\CustomTables\Tools\CustomTable_Data_EditItem.aspx.cs
which is:
DataClassInfo dci = DataClassInfoProvider.GetDataClassInfo(customTableId);
dci.CheckPermissions(PermissionsEnum.Read, SiteContext.CurrentSiteName, MembershipContext.AuthenticatedUser)
And the possible permissions are located in CMS.DataEngine.PermissionsEnum. (Read, Modify, Create, Delete, Destroy)
EDIT:
I'm, dumb. You're assigning a default value to the user param, not an auto-assigned value. I would still check to make sure you're getting the user info you're expecting, because that seems to be the most likely cause for the problem.
You seem to be running into a problem here:
private bool CheckCustomTableReadPermission(UserInfo user = null)
Since you're auto-assigning your user parameter to null when your method is called, the following statement will always be true:
if (user == null)
{
user = CurrentUser;
}
And you will never reach your other statement:
if (user != null)
{
// Checks whether the user has the Read permission for the CMS.MenuItem page type
if (UserInfoProvider.IsAuthorizedPerClass(CustomTableClassName, "Read", SiteContext.CurrentSiteName, user))
{
// Perform an action according to the result
return true;
}
}
So your method will always return false.
The IsAuthorizedPerClass() function checks only the user's permissions for the class that you provide to check against and only the specific permission you provide for it to check (e.g. "Read"). So yes, it's only going to see if the user has the Read permission for your custom table.
I'm not 100% certain what all the permissions are, although it appears to be stored in an enum. I'll get back to you on that one in a bit. Hope this helps :)
The IsAuthorizedPerClass() method will return true only if the user's role has been granted permission explicitly within the role's Permissions for that class. All other times, it will return false even if the user is in fact able to Read/Modify/etc. the custom table.
To get the correct permission strings, you can use CMS.DataEngine.PermissionsEnum.<type>.ToString()
To check whether a user has permissions to Read a specific custom table, you will need to make the following 3 checks in order:
UserInfoProvider.IsAuthorizedPerUIElement("CMS.CustomTables","CustomTables",SiteContext.CurrentSiteName,user)
UserInfoProvider.IsAuthorizedPerResource("CMS.CustomTables", PermissionsEnum.Read.ToString(), SiteContext.CurrentSiteName, user)
UserInfoProvider.IsAuthorizedPerClass(CustomTableClassName, PermissionsEnum.Read.ToString(), SiteContext.CurrentSiteName, user)
My session is not getting destroyed. This is how I set it up in Login.aspx.cs:
Session["User"] = UserName.Text; // Set the session called User.
Link on the MasterPage:
<img src="images/login.png"><span runat="server" id="authspan">Login</span>
The text in the link changes depending on whether the user has session or not:
if (Session["User"] != null)
{
authspan.InnerHtml = "Logout";
}
else
{
authspan.InnerHtml = "Login";
}
This link redirects to Login.aspx file in which on PageLoad I tell the code to close the session. In theory, this should work, right?
protected void Page_Load(object sender, EventArgs e)
{
if (Session["User"] != null)
{
Response.Redirect("Default.aspx"); // Redirect user.
Session["User"] = null;
Session.Remove("User");
}
else
{
// run code that logs the user in, and sets up the session.
}
}
How can I end it for the logged in user correctly?
You must first clear session and then redirect.
Session["User"] = null;
Session.Remove("User");
Response.Redirect("Default.aspx"); // Redirect user.
Also note that, it is safer to remove session id on client side too:
var sessionCookie = new HttpCookie("ASP.NET_SessionId");
sessionCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(sessionCookie);
You should use:
Session.Clear();
Response.Redirect("Default.aspx");
To remove the value from session in different ways
//Set the session variable
Session["User"]=Value;
//Destroy the session variable
Session.Remove("User");
Session["User"]=null;
// Abandon will destroy the session completely, meaning that you need to begin a new session before you can store any more values in the session for that user
Session.Abandon();
//Clearing the session will not unset the session, it still exists with the same ID for the user but with the values simply cleared.
Session.Clear();
Call Session.Abandon(); (and I must write at least 30 chars)
How to check that any of a Session is set or not in ASP.NET C# as we do in PHP
if(session_id() == '')
{
// session has NOT been started
session_start();
}
else
{
// session has been started
}
And in ASP.Net C#
if (Session["userRole"].ToString() == "2")
GridView3.Columns[7].Visible= true;
else{
GridView3.Columns[7].Visible= false;
The above code only checks the session named userRole.
What is the alternate way of the above PHP code to C#?
In order to check if any session key is set try:
if(Session.Keys.Count > 0)
{
Console.WriteLine("Session is filled");
}
else
{
Console.WriteLine("Session is empty");
}
Every item is a 'key' in the Session object. So when the count equals zero, there are no session keys set. Is this what you wanted?
To check if the session key exists in Session collection you have to compare it with null
if (Session["userRole"] != null && Session["userRole"].ToString() == "2")
Edit based on comments, Session is property of Page class and will always exists and will not be null.
This property provides information about the current request's
session. A Session object is maintained for each user that requests a
page or document from an ASP.NET application. Variables stored in the
Session object are not discarded when the user moves from page to page
in the application; instead, these variables persist as long as the
user is accessing pages in your application, MSDN.
Another Solution use try catch
try
{
if (Session["userRole"].ToString() == "2")
GridView3.Columns[7].Visible = true;
else
GridView3.Columns[7].Visible = false;
}
catch (Exception)
{
GridView3.Columns[7].Visible = false;
}
Edit Some have expressed their dislike for my particular solution presented in this problem, but please don't waste my time suggesting completely alternative methods. I have no control over the requirements of what I am working on. If you disagree with it and don't have an answer, just move along. Thanks.
For starters, this is a practice project and will not be used by the general public. I need to secure some pages in my website using session properties for username. This occurs (the username saved into session) when a correct username and password combo is entered. My boss reviewed my implementation and said that "storing the username value into the HttpSessionState directly is wrong, you should set the username property of the session, and store the session object into the HttpSessionState". Now I think I understand what parts of my code he is referring to, but changing this breaks the security (anyone can use a direct link to a page once a single user has logged in).
Make sure to read the comments in code, I added them to describe the lines in question.
What worked in terms of security, but username is stored directly into HttpSessionState:
//login.ascx.cs
private void Login_Click(object sender, EventArgs e)
{
if (sender == null || e == null)
{
throw new ArgumentNullException("Null Exception: Login_Click");
}
User user = new User();
user.Login(_username.Text, _password.Text);
if (user.IsValid() && user.GetIsUser() != false)
{
user.Save();
//the line below is what I used to make the secure pages work properly.
//but based on what my boss says, I think this is what should be changed.
Session["Username"] = _username.Text;
//What i tried instead was to set 'MySession.Current.Username = _username.Text;'
//which allowed successful login, but the pages became insecure once again.
Response.Redirect("Secure/Default.aspx");
}
else
{
DisplayErrors(user._validationErrors);
}
_errors.Text = errorMessage;
}
and MySession.cs
public string Username
{
get
{
if (HttpContext.Current.Session["Username"] == null)
{
return string.Empty;
}
else
{
return HttpContext.Current.Session["Username"].ToString();
}
}
set
{
//when the line below is uncommented, the secure pages are vulnerable
//but if I comment it out, they work properly.
//HttpContext.Current.Session["Username"] = value;
}
}
So how can I Set the username property of the session, and store the session object into the HttpSessionState while still maintaining a secure site?
EDIT: #Win, within Secure/Default.aspx.cs
private void Page_load(object sender, System.EventArgs e)
{
...
if((string)Session["Username"] != _labelusername.Text)
{
Response.Redirect(redirectLogin); //to login page
}
else {} //success
}
You should look into FormsAuthentication. There are many examples online like this one:
http://bradkingsley.com/securing-asp-net-pages-forms-authentication-c-and-net-4/