I am developing an user authentication site.
I have a login page, "Login.aspx" in which i have provided a login control.
In the web.config,
<authentication mode="Forms">
<forms name=".AuthenticationCookie" loginUrl="Login.aspx" protection="All" timeout="60" path="/">
<credentials passwordFormat="Clear">
<user name="Jack" password="Jerry"/>
</credentials>
</forms>
</authentication>
<authorization>
<deny users="*"/>
</authorization>
In the login.aspx.cs page,
I have provided,
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
if (FormsAuthentication.Authenticate(Login1.UserName,Login1.Password))
{
FormsAuthentication.SetAuthCookie(Login1.UserName,true);
Label1.Text = "Login Successful";
Login1.InstructionText = "";
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, true);
Response.Redirect("Success.aspx")
}
else
{
Label1.Text = "You are not an authentic user";
}
}
}
but however, while execution instead of going to success.aspx
with the url http://localhost/Login.aspx?ReturnUrl=%2fSuccess.aspx
Why is this so?
If you want to set the forms auth cookie yourself and redirect correctly based on the ReturnUrl query string parameter, you should look at the FormsAuthentication.RedirectFromLoginPage method. In your example, it would be:
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, true);
That method sets the appropriate Forms auth cookie / ticket and then redirects based on the presence or absence of the ReturnUrl parameter. (If absent, it goes to the configured default page.)
Hope this helps,
Donnie
Related
I am trying to retrieve the current user in my web application that uses ASP.NET Forms authentication.
However, System.Security.Principal.WindowsIdentity.GetCurrent().Name returns domain\windowsUser, NOT the username that was used in the FormsAuthentication.RedirectFromLoginPage method.
I am using Forms authentication in my config file:
<authentication mode="Forms">
<forms loginUrl="Views/Login.aspx" name=".ASPXFORMSAUTH" timeout="1" cookieless="UseUri">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
I am also trying to follow Microsoft's walk through and retrieve the Authentication ticket using the following snippet:
if (Request.IsAuthenticated)
{
var ident = User.Identity as FormsIdentity;
if (ident != null)
{
FormsAuthenticationTicket ticket = ident.Ticket;
var name = ticket.Name;
}
}
However, ident is always null because it's WindowsIdentity not FormsIdentity. What's wrong here?
Thank you!
Use User.Identity.Name to get the user name.
Windows authentication does not use the FormsAuthenticationTicket.
I'm noticing some strange behavior with a shared authentication cookie setup, here's my scenario.
I've got two applications with the domains similar to the following:
login.mydomain.com
system.mydomain.com
I am redirecting the user to login.mydomain.com and dropping a the cookie from there on mydomain.com like so.
system.mydomain.com:
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.User == null || !Request.IsAuthenticated)
{
HttpContext.Current.Response.Redirect("http://login.mydomain.com");
}
}
login.mydomain.com
protected void btnSubmit_Click(object sender, EventArgs e)
{
pnlLoginNotice.Visible = true;
if (Membership.ValidateUser(txtUsername.Text, txtPassword.Text))
{
HttpCookie cookie = FormsAuthentication.GetAuthCookie(txtUsername.Text, chkRememberMe.Checked);
cookie.Domain = "mydomain.com";
Response.Cookies.Set(cookie);
}
}
Web.config:
<authentication mode="Forms" >
<forms timeout="2880" name=".COMMONAUTH" />
</authentication>
Now the behavior I'm seeing is that I'm finding the .COMMONAUTH cookie dropped under system.mydomain.com sometimes, while there's the same cookie under mydomain.com. I've noticed that it shows up after some time of inactivity on the site.
Is it possible that asp.net is dropping the cookie on it's own to keep the forms authentication alive?
UPDATE
I've tried the following approaches
1:
system.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="1" name=".COMMONAUTH" />
</authentication>
login.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="2" name=".COMMONAUTH"/>
</authentication>
When refreshing a page in system.mydomain.com after one minute has passed, I get the .COMMONAUTH cookie under system.mydomain.com
2:
system.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="2" name=".COMMONAUTH" />
</authentication>
login.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="1" name=".COMMONAUTH"/>
</authentication>
When refreshing a page in system.mydomain.com after one minute has passed, I get logged out.
3:
system.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="1" name=".COMMONAUTH" domain="mydomain.com" />
</authentication>
login.mydomain.com Web.config
<authentication mode="Forms" >
<forms timeout="2" name=".COMMONAUTH" domain="mydomain.com"/>
</authentication>
When refreshing a page in system.mydomain.com after one minute has passed, all remains the same and I'm still authenticated. Not sure what will happen when a 3rd application will be introduced to this setup
Conclusion
I think my issue is comming from not setting the domain in the web.config, so system.mydomain.com is trying to refresh the cookie but is using its own domain since I am not telling it where it should be doing it.
My problem is that these applications will have different domain bindings and they will be hosted once for multiple clients. I cannot set FormsAuthentication.CookieDomain as it is read only.
Should I go with option 2, and give my cookie issuer a lower timeout from the other applications? Will this have any implications?
I ended up doing this, I won't mark this as the answer just yet, jut in case anyone points out any issues with it.
In Global.asax
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.User == null || !Request.IsAuthenticated)
{
HttpContext.Current.Response.Redirect(GetLoginUrl());
}
else if (Context.User.Identity is FormsIdentity)
{
HttpCookie cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
{
FormsAuthenticationTicket currentTicket = FormsAuthentication.Decrypt(cookie.Value);
if (currentTicket == null && currentTicket.Expired)
{
return;
}
FormsAuthenticationTicket newTicket = currentTicket;
if (FormsAuthentication.SlidingExpiration)
{
FormsIdentity id = (FormsIdentity)Context.User.Identity;
newTicket = FormsAuthentication.RenewTicketIfOld(id.Ticket);
}
if (currentTicket != newTicket)
{
cookie.Value = FormsAuthentication.Encrypt(newTicket);
cookie.Expires = newTicket.Expiration;
cookie.Domain = WebGlobal.GetCurrentContextDomain();
Response.Cookies.Set(cookie);
}
}
}
}
With the information you provided, you also have the option to modify dynamically your configuration in the Application_Start to set the correct value for the domain attribute if it is not already set :
See :
http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k%28System.Configuration.ConfigurationManager%29;k%28TargetFrameworkMoniker-.NETFramework
Hope this will help
I guess an hint can be found in the timeout attribute description of the forms element:
http://msdn.microsoft.com/en-us/library/1d3t3c61%28v=vs.80%29.aspx
To prevent compromised performance, and to avoid multiple browser
warnings for users who have cookie warnings turned on, the cookie is
updated when more than half of the specified time has elapsed. This
might cause a loss of precision. The default is "30" (30 minutes).
is it also set to 2880 minutes on system.mydomain.com ? or is it the default 30 minutes value ? if so, you should see a cookie change after 15 minutes.
Does the problem still happen if you set up your web.config like this ?
<authentication mode="Forms" >
<forms timeout="2880" name=".COMMONAUTH" domain=".mydomain.com" />
</authentication>
I'm new to ASP.NET and have been trying to solve this for awhile now.
I've came across this blog, and everything looks to be good, except one thing: the below code always evaluates to false in HttpContext.Current.User.Identity is FormsIdentity in this code snippit:
protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Get the stored user-data, in this case, our roles
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
When I used breakpoints, it turned that my PC name is the current user, which I think is not a FormsIdentity.
Web.config:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
</configuration>
What am I missing here? and how to tell HttpContext of the current user after a sucessful login?
If you want users to have a FormsIdentity, then you need to turn on FormsAuthentication in your web.config file. In your element, you need to populate the authentication and authorization nodes. (For example, see the section of the blog post you mentioned titled "Securing Directories with Role-based Forms Authentication") Right now these elements are not present in your web.config file, and so Forms Authentication is not happening. A configuration like this is typical:
<system.web>
<authentication mode="Forms">
<forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" />
</authentication>
<authorization>
<deny users ="?" />
<allow users = "*" />
</authorization>
</system.web>
The node instructs ASP.Net to use forms authentication, while the node denies access to the site for any user who is not authentication.
More information can be found here and here
I have a web.config with the following:
<system.web>
<customErrors mode="Off"/>
<authentication mode="Forms">
<forms loginUrl="Login.aspx" name="SIPE_ASPXAUTH">
<credentials passwordFormat="Clear">
<user name="user1" password="123456"/>
<user name="user2" password="123456"/>
<user name="user3" password="123456"/>
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<compilation debug="true"/>
This web.config always redirects me to the following url
http://localhost:53077/Login.aspx?ReturnUrl=%2fDefault.aspx
My start page is a Login.aspx and even after entering the correct credentails, it redirects me to the above url.
So here's what I did.
I took out the name property in the
<forms loginUrl="Login.aspx">
and left everything else untouched.
It works perfectly.
Can anyone pls explain why.
I understand that this is a cookiename and the default is ASPXAUTH. This cookie is used to authenticate a user. Also it is stored in tools..options...
What is the use of setting this cookiename. Is it to allow cross browser functinality.n
How would I make this to work by having the name property in the <forms loginUrl="Login.aspx">
Thank u
config setting is seems to be OK but you have write some code in your login page's code behainsd also for form authentication. After checking user name & password is corrent you have to write below code :
FormsAuthentication.SetAuthCookie(
this.TextBox_username.Text.Trim(), flase);
FormsAuthenticationTicket ticket1 =
new FormsAuthenticationTicket(
1, // version
this.TextBox_username.Text.Trim(), // get username from the form
DateTime.Now, // issue time is now
DateTime.Now.AddMinutes(10), // expires in 10 minutes
false, // cookie is not persistent
"HR" // role assignment is stored
// in userData
);
HttpCookie cookie1 = new HttpCookie(
FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(ticket1) );
Response.Cookies.Add(cookie1);
For more detail on Form Authentication Click Here
Site Details which uses the single sign on,
1. http:\\webgate.abcltd.com
2. http:\\sales.abcltd.com
3. http:\\emp.abcltd.com
webgate application does the authentication and authorization. others(sales,emp) uses the webgate application. when any one access the any page from sales/emp site, they will be redirected to webgate's login page(here i have used form authentication. the configurations are below)
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
protection="All"
name="WebGateSecurity"
path="/"
domain="abcltd.com"
defaultUrl="ApplicationList.aspx"
enableCrossAppRedirects="true"/>
</authentication>
<authorization>
<deny users="?" />
</authorization>
<machineKey validationKey="2C0904BC344116CC6FFD3DD7087C942878C41B7F861555651E69C7B72F9A7DF6BC3B63BFF0F1438DFB863EE3EAC62CBFFECA7482D3758888E7CDACDBBAE136D5" decryptionKey="A60EC9E480CB3BBC48D1D2B7FFF9E945FBA46196AD3029187022ADE8F7B99B25" validation="SHA1" decryption="AES" />
User credentials is validated against the data store and the authentication ticket/cookies are being created as below
var authTicket=FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), false, userActions, FormsAuthentication.FormsCookiePath);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);
If the given credentials are correct, i am tring to redirect to requested url as below
if (Request.Params["ReturnURL"] == null || Request.Params["ReturnURL"].EndsWith("/Logout.aspx") || Request.Params["ReturnURL"].EndsWith("/Error.aspx"))
Response.Redirect(FormsAuthentication.DefaultUrl);
else
{
//Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
FormsAuthentication.RedirectFromLoginPage(username, false);
}
I have used the LoginStatus Control(placed in master page) which is let the user to perform the sign in/sign out from webgate app. When user sign out, the following code will be executed in order to remove the cookie.
protected void LoginStatus1_LoggingOut(object sender, LoginCancelEventArgs e)
{
FormsAuthentication.SignOut();
HttpCookie httpCookie = Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName];
if (httpCookie != null)
{
httpCookie.Domain = "abcltd.com";
httpCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(httpCookie);
}
}
Configuration in other applications(sales and emp) are follows
<authentication mode="Forms">
<forms loginUrl="http://webgate.abcltd.com/Login.aspx" name="WebGateSecurity" protection="All" path="/" domain="abcltd.com" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
<machineKey validationKey="2C0904BC344116CC6FFD3DD7087C942878C41B7F861555651E69C7B72F9A7DF6BC3B63BFF0F1438DFB863EE3EAC62CBFFECA7482D3758888E7CDACDBBAE136D5" decryptionKey="A60EC9E480CB3BBC48D1D2B7FFF9E945FBA46196AD3029187022ADE8F7B99B25" validation="SHA1" decryption="AES" />
My problem is: sign out is not working. In details if i say: after sign out, i able to access the any pages from webgate,sales and emp application.
Please help me.
That's because you are using a different domain name in web.config:
domain="vrxstudios.com"
and
domain="abcltd.com"
so no single sign on possible. In your sign out method you cannot remove a cookie that belongs on abcltd.com from vrxstudios.com:
if (httpCookie != null)
{
httpCookie.Domain = "abcltd.com"; // this is not possible from vrxstudios.com
httpCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(httpCookie);
}
What you could do is redirect to a sign out page on abcltd.com which will do the job.