I am developing a SQL Server based async browser chat with ASP.NET MVC in C#. My project consists of a web project, a winforms application and a database of course. In my database, I have a table called User with a DateTime property named LastLogin and another boolean property named isOnline. I want to set isOnline to false, if (LastLogin + 15sec =< DateTime.Now), so 15seconds is the timeout. What is the best solution to solve this problem in your opinion?
Do you have suggestions for a better title?
First off, checkout something like the SignalR source to see how they're doing it. Second, I'd look into doing it via Session && Logout.
In your Global.asax
void Session_End(Object sender, EventArgs E) {
// update the database with "offline"
}
In your logout code
protected void LogOut_Click(object sender, EventArgs e)
{
// logout
// update database with "offline"
// redirect to public page of your choosing.
}
Related
We are using an application that runs on asp.net and C#. When a user is logged in, their profile information is displayed (name, id number) on a Profile page (information comes from MSSQL). I would like to get the id number for the logged in user and pass that value to an embedded form (this part I know I can do), the struggle is figuring out how to get the id number from one page to the other page.
I am not proficient with C# or asp.net but I did find where the id value is at, I am not sure how to call it from my form page?
Pass Values Between ASP.NET Web Forms Pages
The following options are available even if the source page is in a different ASP.NET Web application from the target page, or if the source page is not an ASP.NET Web Forms page:
Use a query string
Get HTTP POST information from the source page
The following options are available only when the source and target pages are in the same ASP.NET Web application:
Use session state
Create public properties in the source page and access the property
values in the target page
Get control information in the target page from controls in the
source page
The main factor that should influence your approach should be the fact that this is a secure application and you do not want the information being passed to be prone to scrutiny.
First Option:
Use Cookies
On your firstPage.aspx
HttpCookie appCookie = new HttpCookie("IdValue");
appCookie.Value = "The value of your id here" or id.ToString();
appCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(appCookie);
To get:
SecondPage.aspx
HttpCookie aCookie = Request.Cookies["IdValue"];
String getValue = aCookie.Value.ToString();
Cookies expires depends on your Settings here appCookie.Expires = DateTime.Now.AddDays(1); it can be AddDays('MoreNumberofdays') like AddDays(4) it will expires in 4 days. Something like that.
some additional Guide
Second Option:
Class:
public class Class1
{
public static string storevalue;
}
Page1.aspx
protected void Page_Load(object sender, EventArgs e)
{
Class1.storevalue = "This is the value from page1";
Response.Redirect("WebForm2.aspx");
}
Page2.aspx
protected void Page_Load(object sender, EventArgs e)
{
string getvalue = Class1.storevalue;
}
Of course that Request.UserHostAddress way is great, however in Application_Start() the Request object isn't exists yet.
I want to first guess the location of user by his/her IP - just one time - as he/she enters the web site, and set the default locale for him/her. Then I'll manipulate it some where else.
I think that there must be an event to be overridden in Global.asax which Request exists in it, However I can't find that event...
Indeed any alternate trick will be appreciated...
Update:
In fact, I'm developing a multilingual web site and I use MaxMind GeoIP to get the country of users by their IP. So, I want to find a way in order that when a user enters the site (only and only the first request) I retrieve his/her country and store it in Session or a global variable.
I know that I can achieve my goal any where else by Request.UserHostAddress and I have not any problem with it - just one line overhead for each request isn't an issue at all for this small app.
However I wonder if it is possible to set that global variable, only and only once...!?!
Application_Start() is not right event, in which you can do this. It will not run for every request from your user, it does some basic initialization of asp.net application.
Better solution is to user, for example
protected void Application_BeginRequest(){}
which runs on beginning of request from client.
About earliest event, in which both request and session will be available... Seems like it is
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (System.Web.HttpContext.Current.Session != null)
{
if (Session["locale"] != null)
{
//already set variable.
}
else
{
//set some variable
Session["locale"] = "code";
}
}
}
But what exactly do you want to you mean by "setting locale based on IP"? Can you clarify this task? 'Cause in general, for each request execution this "locale" information must be set.
You should do this like this
public void Init(HttpApplication context)
{
context.BeginRequest += (Application_BeginRequest);
}
private void Application_BeginRequest(object source, EventArgs e)
{
var context = ((HttpApplication) source).Context;
var ipAddress = context.Request.UserHostAddress;
}
It may be solved by using GlobalFilterCollection. You can override the method OnActionExecuting and add the necessary logic. This article: ASP.NET MVC 4 Custom Action Filters may help.
I'm trying to write a website which based on ASP.Net. When I made a login page with username and Password, and also connected to a SQL-server.
But when I type in the right username and password. It will need to click login twice to login. Once I login, when I go back to the login page. No matter what I'm trying to type in the username and password textbox. The system will always log me in. I heard that the session can help, but I don't have any idea how to use it.
Is there anyone could help me? Or show me some usable code samples please?
Thank you
Jimmy
I second #GojiraDeMonstah's suggestion and would also recommend that you try to use Microsoft's out of the box (OOTB) functionality for handling website security (i.e. authentication, authorization, user management, password reset etc.) as much as possible. There's no reason to go reinventing the wheel when it's all there for you. You can even extend the existing functionality to create your own custom authentication provider but you really want to avoid trying to write one from scratch especially if you're new to this stuff.
Microsoft provides an infinite number of tools and tutorials to allow you to setup all this stuff so easily. Don't try creating your own database unless you really, really have to. Just use the one they provide you and work from that as a starting point.
Here is another great resource that provides a more visual tutorial to show you how easy it is.
Good luck!
The process of supplying a username and password (credentials) and then using the supplied name & password to verify a user is called Authentication. If you google asp.net authentication you will get a zillion results. Here's a good start --> http://support.microsoft.com/kb/301240
Write code like this
FirstPage.aspx(On your first page Login button click)
protected void Login_Click(object sender, EventArgs e)
{
Session["UserName"] = txtUserName.Text;//Store username in session
}
SecondPage.aspx(after login on next page)
protected void Page_Load(object sender, EventArgs e)
{
LabelUserName.Text = Session["UserName"].ToString();//Show username on a label
}
Hope it helps ....
The easiest way I have found is to download the sample pages provided in this example here.
Use the Global.asac file so you don't have to add login code to each and every page in your application.
In the file "Global.asax", define your session in the function "Session_Start()"
protected void Session_Start(Object sender, EventArgs e)
{
//The first Session "Logged" which is an indicator to the
//status of the user
Session["Logged"]="No";
//The second Session "User" stores the name of the current user
Session["User"]="";
//The third Session "URL" stores the URL of the
//requested WebForm before Logging In
Session["URL"]="Default.aspx";
}
In each of the pages you want only authenticated access to check if the user is Logged or not like this:
private void Page_Load(object sender, System.EventArgs e)
{
if(Session["Logged"].Equals("No"))
{
....
}
else
{
....
}
}
In your Login.aspx page check the user name and password from your database with a function like:
if(CheckUser(UserNametxt.Text.Trim()) && CheckPassword(Passwordtxt.Text.Trim())
{
....
}
else
{
....
}
In your codebehind define the functions CheckUser() and CheckPassword() by connecting to your database and passing the variable from the login page.
Download sample files here.
I am currently using session to hold the user ID at my web application. And i read a lot about sessions is evil, so my plans is to find another solution.
So my next step is to use encrypted cookie.
Something like:
userInformation: ENCRYPT(UserID,subdomain,someComputerUniqueValue,hashvalueOftheString)
each user has their own subdomain, so the UserID and Subdomain must match.
But. Now at almost every page i call the session value to get the userID.
I want to change this to some kind of variable, but what kind of variable?!
I am now setting the session value inside a httpmodule. in the
public void Application_PreBeginRequest
Is it possible to create a variable within application_prebeginRequest and read it somewhere else during the creation of the page. for example in the masterpage, och the contentpage. or the classes that is used at that specific page.
WHen the page is created and sent to the client, the variable should die.
What kind of variable am i looking for? is it global variable? if not, what is global variable?
Thanks for reading!
Mattias R.
Edit:
This cookie is not for authentication. I want to save the ID of the user connected to the subdomain, so i dont have to run the "SELECT ID from account where subdomain='somethin'" query each time a page is visited.
You can store what you need inside the HttpContext.Current.Items. Items put inside that will live only during the current web request and will be available globally in your web application.
// Global.asax
void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items["hello"] = DateTime.Now;
}
// Default.aspx
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = HttpContext.Current.Items["hello"].ToString();
}
}
By the way, at Application_BeginRequest event, the Session object isn't available.
For more information about HttpContext.Current.Items, look at https://web.archive.org/web/20201202215202/https://www.4guysfromrolla.com/articles/060904-1.aspx.
Once the user is authenticated, why don't you log them in with FormsAuthentication.SetAuthCookie?
You can then retrieve the currently logged in user using HttpContext.Current.User.Identity.Name.
Session is not "evil" Session is stored on the server, and for small amounts of data such as what you suggest, it scales very well.
I have a relatively simple ASP.Net application that I have built some simplistic security into. The user logs in with a username and password and I check it against the DB. If it is successful I store a User object for them on a session variable called "UserID" and redirect them to the same page, only this time they dont see the login panel. (Mmm could just hide it dynamically but I think that would cause a page reload anyway)
On my Default.aspx page I have the following code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["UserID"] == null)
{
LoginPanel.Visible = true;
}
}
protected void btnLogin_Click(object sender, EventArgs e)
{
Security security = new Security();
Session["UserID"] = security.LoginUser(txtUsername.Text, txt2Password.Value);
if (Session["UserID"] != null)
{
Response.Redirect("~/default.aspx");
}
}
Right, so far so good. Also worth mentioning at this point is the master page:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["UserID"] == null)
{
//Check that we are not already on the default.aspx page.
//Don't want to cause infinite redirect here
if (!Request.Path.ToLower().Contains("default.aspx"))
{
Page.Response.Redirect("~/Default.aspx");
}
}
else
{
//Otherwise we get the UserObject from the session and display menu items //based on the role. Nothing fancy.
}
}
//Bad naming. This a logout link on the master...
protected void Unnamed1_Click(object sender, EventArgs e)
{
Session["UserID"] = null;
Page.Response.Redirect("~/Default.aspx");
}
Now all of this works perfectly on my local instance of IIS. As soon as I deploy this to our production server and I click on one of my menu items and navigate say to Search.aspx it chucks me back to my Default.aspx page with the LoginPanel visible??? Also that is in Firefox. With IE I can click on the Search.aspx menu link and it takes me to the page, but clicking on an edit link in my GridView also chucks me back to the Default.aspx page with the LoginPanel showing.
I'm no ASP.net expert at all and I'm at wits end. So please word Answers with as little as possible jargon and so forth and post links to msdn for docs and such so that I don't just resolve this, but actually understand why this has been giving me nightmares.
TIA
Don't store user identifiers or other sensitive information in the session, implement IIdentity and IPrincipal with Forms authentication instead (though this doesn't completely rule out information exposure altogether).
This enables easy access to certain elements in the nature of what you need:
//to sign-in:
FormsAuthentication.SignIn("username", createPersistentLogin);
//to sign-out:
FormsAuthentication.SignOut();
//user data access:
Page.User.IsInRole("requiredRole");
Page.User.Identity.IsAuthenticated;
Page.User.Name;
A couple of snippets from MSDN to explain the meaning of this:
The .NET Framework provides a
role-based security implementation in
the System.Security.Principal
namespace, which you can use for
authorizing and authenticating users
in your application.
An IIdentity encapsulates an
authenticated user. An IPrincipal is a
combination of the identity of the
user and any roles he or she has. You
can use the predefined identity and
principal classes in the
System.Security.Principal namespace or
you can add custom authentication by
creating classes that implement the
interfaces.
Care should be used when granting
permissions to work with IIdentity
objects, because these objects make
sensitive user-related information
available. You should protect the
application's current IPrincipal
object from changes because the
application's authorization capability
is based on its current principal.
You can get information on doing this from MSDN.
maybe a bit off topic but I would recommend to use built in login functionality, that means Login Controls, Membership and Authentication. Then you don't have to mess with Session
http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
then you can do Membership.GetUser().ProviderUserKey for example to get the key
Verify if in your production server the Web.Config file of your site contains this line, or something like this :
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
It must be inside element.
It is to verify wich sessionState are you using.
See the link :
Asp.NET Session State