I started programming in c# for a few days ago, so I am a total newbeginner at this. Based on my experience in other languages, I found it somewhat "simple".
I am building a system where users are logging in to my application, which is working. I want to have a "remember me"-setting where the information is stored locally. What is the best way to do this? I'll only save the username and the password-hash.
Edit: This is a desktop-application. The login-information is sent to a php-script simply using HttpWebRequest
You can use the ConfigurationManager Class to manage your application's settings.
you can use this function to add new Keys to your configuration file:
public bool setSetting(string pstrKey, string pstrValue)
{
Configuration objConfigFile =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
bool blnKeyExists = false;
foreach (string strKey in objConfigFile.AppSettings.Settings.AllKeys)
{
if (strKey == pstrKey)
{
blnKeyExists = true;
objConfigFile.AppSettings.Settings[pstrKey].Value = pstrValue;
break;
}
}
if (!blnKeyExists)
{
objConfigFile.AppSettings.Settings.Add(pstrKey, pstrValue);
}
objConfigFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
return true;
}
and then save up your username (for example)
setSetting("username", usernameTextBox.Text);
Once your application starts up, you can read the information you saved earlier from your ConfigurationManager
usernameTextBox.Text = ConfigurationManager.AppSettings["username"];
you can create Application Settings in C#
here's what you will do.
don't forget to encrypt it.
If you're using ASP .NET,you can set authentication cookie when you're logged in user by second parameter
FormsAuthentication.SetAuthCookie(model.UserName, true);
Second parameter sets cookie to your request and makes "Remeber Me" option.
What I understand from your question is, php file is server and for client you are using windows form. Your are doing some kind of HTML scrapping and displaying the result HTML in your win-form. If this is the what you are doing then
//1. Create a dictionary to store cookie collection
public static Dictionary<string, Cookie> CookieCollection { get; set; }
//2. Store cookie in that collection
foreach (Cookie clientcookie in response.Cookies)
{
if (!CookieCollection.ContainsKey("AuthCookieName"))
CookieCollection .Add(userName, clientcookie);
else
CookieCollection ["userName"] = clientcookie;
}
//3. If remember me is clicked then send the same while creating request
request.CookieContainer.Add(request.RequestUri,
new Cookie("AuthCookieName", CookieCollection ["userName"]));
Where AuthCookieName is the name of authentication cookie. The only downside is when the application exists all the cookie stored in the dictionary would be gone. The solution could be serializing the cookie and storing it in database, if remember me is checked.
Related
I am new to gamesparks, but so far I have set up a login/register function, which works like it should, but... How do I ensure that the user don't have to login next time he or she opens the app?
I found this in which I read that I can just run this:
GameSparkssApi.isAuthenticated().
First off all, in all other tutorials it states that it should be: GameSparks.Api.xxxx. Even when trying this I do not find isAuthenticated() anywhere.
GameSparks.Api.isAuthenticated();
I am hoping that someone can cast some light on this.
You can use Device Authentication for this purpose. This method of auth sets an access token for the device you are on. This token is stored and the client and gotten in the request. these requests are structured like so:
new GameSparks.Api.Requests.DeviceAuthenticationRequest()
.SetDeviceId(deviceId)
.SetDeviceModel(deviceModel)
.SetDeviceName(deviceName)
.SetDeviceOS(deviceOS)
.SetDeviceType(deviceType)
.SetDisplayName(displayName)
.SetOperatingSystem(operatingSystem)
.SetSegments(segments)
.Send((response) => {
string authToken = response.AuthToken;
string displayName = response.DisplayName;
bool? newPlayer = response.NewPlayer;
GSData scriptData = response.ScriptData;
var switchSummary = response.SwitchSummary;
string userId = response.UserId;
});
You can find more on this method in our documentation: https://api.gamesparks.net/#deviceauthenticationrequest
Regards Patrick, GameSparks.
i am new to asp.net. my question is that how one can save login userid in asp.net webform?
code i am writing in asp.net webform is:
foreach (var s in db.Users)
{
if (tbUserName.Text==s.user_name && tbPassword.Text == s.user_password)
{
if (string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
{
FormsAuthentication.SetAuthCookie(tbUserName.Text, false);
Response.Redirect("~/");
}
else
{
FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, false);
}
flag = 1;
break;
}
else
flag=0;
}
if(flag==0)
{
tbUserName.ErrorText = "Invalid user";
tbUserName.IsValid = false;
}
}
As Tim said, you can get the authenticated user with
User.Identity.Name
You can also get the AuthenticationType and IsAuthenticated properties from the same object.
A suggestion would be to NOT query your DB for all of the users and then loop through them for the correct one. Based off of the user input, you should query the db for the one and only user which matches the form post.
Based off of what you wrote, it looks like the passwords are in clear text and not encrypted, which is a huge security issue. Being new to .Net, take a look at the .Net Membership Providers or SimpleMembership or a comparable pattern.
Good luck!
I would suggest you look at using the Session object to store the user ID. A Session will be available throughout that user's session on the site. Thus, you can call Session anywhere in your site's code to reference that user ID.
For example, to store the id, simply do this, pretend we're in Page_Load()
Session["UserId"] = userID // Or wherever you get the ID from.
then in your code behind, you can do this:
string userId = Session["UserId"]
If the user ID is a number, say an int, then you will need to cast the userID:
int userId = 0;
int.TryParse(Session["UserID"], out userID)
Quick dirty link to a Session example :
http://asp.net-tutorials.com/state/sessions/
My web application logs into a web api. This needs an email and password. I cannot hash these in my database because the api requires the password in plain text.
How can I store my web api credentials in a safer way than plain text, xor, or base64? Is there a 'proper' solution for this sort of thing?
Yes there is, the ProtectedData class, it lets you encrypt a object tied to a windows user acount, so if the user.config file is copied to another user/computer it will not work
In your Settings file, create two string properties named ApiUsername and ApiPassword, then click "View Code at the top and add the following functions
internal sealed partial class Settings {
private MD5 md5 = MD5.Create();
public global::System.Net.NetworkCredential ApiLogin
{
get
{
global::System.Net.NetworkCredential tmp = null;
if (ApiPassword != "")
{
tmp = new System.Net.NetworkCredential();
tmp.UserName = ApiUsername;
try
{
tmp.Password = System.Text.Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(ApiPassword), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(ApiUsername.ToUpper())), DataProtectionScope.CurrentUser));
}
catch
{
tmp.Password = "";
}
}
return tmp;
}
set
{
global::System.Net.NetworkCredential tmp2 = value;
ApiUsername = tmp2.UserName;
ApiPassword = Convert.ToBase64String(ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(tmp2.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp2.UserName.ToUpper())), DataProtectionScope.CurrentUser));
}
}
}
This will add a accessable property called ApiLogin which will contain a NetworkCredential with the decrpted password, when you save the credentials to the disk it stores it in that encrpted protected form that can't be copied to other users.
If the decryption fails it sets the password to blank in the returned credential. If you want the decrption to work on any useraccount on that single machine change the ProtectionScope to DataProtectionScope.LocalMachine.
in my app. there's a log in mechanism which save a cookie with the info of the user who just logged in
private void CreateCookie(LoginEventArgs args)
{
HttpCookie cookie = new HttpCookie("user");
cookie.Values["name"] = args.User_Name;
cookie.Values["id"] = args.ID;
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
}
on my master page load i perform a check to see if this cookie exists or not :
HttpCookie cookie = Request.Cookies["user"] ;
if( (cookie != null) && (cookie.Value != ""))
{
if (Session["user"] == null)
Login_Passed(this, new LoginEventArgs(cookie.Values["name"].ToString(), int.Parse(cookie.Values["id"])));
}
now if i Log in ( Create A cookie ) , close the browser , and run my app. again the cookie
exists it's values are correct and the user is "automatically" logged in .
if i first redirect to a different content page from the start up content page
the cookies values are also intact ,
the problem is when i redirect back to a different content page a second time,
the master page loads , makes the check
the cookie exists but the values are deleted ...
any ideas on why this happens ?
btw maybe the way i log out could be the reason for this problem :
when i log-out i create a cookie with the same name that expires 1 day ago .
private void Remove_Cookie()
{
HttpCookie cookie = new HttpCookie("user");
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
}
in the case iv'e described i don't log-out formally , i just end my app , so this shouldn't
have any effect .
o'k , the problem was unthinkable
special thanks to Peter Bromberg
http://www.eggheadcafe.com/tutorials/aspnet/198ce250-59da-4388-89e5-fce33d725aa7/aspnet-cookies-faq.aspx
in the section of the Article " The Disappearing Cookie "
the author states that if you have a watch on Response.Cookies["cookie_name"]
the browser creates a new empty cookie that overrides your cookie .
i used such a watch which made my cookie loose it's values ,and when i took it off the cookie kept its values.
the moral is DON't WATCH Response.Cookies[" "]
also i read in some other post that if you check
if( Response.Cookies["cookie_name"] != null )
for example it also gets overridden.
To reiterate and build upon what has already been stated (yes, I know this is a 4 year old question) I have found it best to build a utility to handle this - mostly because I want to check that specific cookie often.
This will not touch the Response but only read from the Request.
public static HttpCookie GetCookie(string cookieName)
{
HttpCookie rqstCookie = HttpContext.Current.Request.Cookies.Get(cookieName);
/*** NOTE: it will not be on the Response!
* this will trigger the error noted in the original question and
* create a new, empty cookie which overrides it
*
HttpCookie respCookie = HttpContext.Current.Response.Cookies.Get(cookieName);
*
*/
if (rqstCookie != null && !String.IsNullOrEmpty(rqstCookie.Value))
{
// is found on the Request
return rqstCookie;
}
else
{
return null;
}
}
rule-of-thumb
Always read from the Request and write to the Response.
Thanks eran! this post was exactly what I needed
try the following:
If you are developing on your local machine, put your app on some free web page, so there will be no 'special treatment' because you're in the local host.
If you already are on a web-server, and if the re-directions are between tow different domains, you may want to search google for 'same origin policy' or read this: http://en.wikipedia.org/wiki/Same_origin_policy (the document talks about javascript, but its true also for cookies).
Use the following approach to get a value from cookies:
public string GetValueFromCookies(HttpCookieCollection cookies)
{
if (cookies == null)
{
throw new ArgumentNullException(nameof(cookies));
}
// check the existence of key in the list first
if (Array.IndexOf(cookies.AllKeys, key) < 0)
{
return null;
}
// because the following line adds a cookie with empty value if it's not there
return cookies[key].Value;
}
I just realized that this cookie is not showing up like it should, and I checked the code which was not written by me but I am pretty sure that this is NOT enough to create a cookie right??
public static void CreateSSOCookies(string tokenID)
{
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Domain = System.Web.HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToString().ToLower();
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Value = tokenID.ToString();
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Path = "~/";
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Expires = DateTime.Now.AddDays(7);
}
If it does work, where is the cookie then? Is the cookie name 'ssocookies' ?
I must admit I didn't know, but apparently it does create a cookie. I've tested it, it works.
See http://msdn.microsoft.com/en-us/library/78c837bd.aspx
So far I had always used the new HttpCookie() method, which seems much .NET-like to me than a collection magically adding a cookie with the right name on first reference. I would still recommend being more explicit about creating the cookie like that, especially seeing some of the incorrect answers here :)
Edit:
The path "~/" is indeed probably not what you want. Use
// Removed some of the current context stuff for readability
Response.Cookies["ssocookies"].Path = VirtualPathUtility.ToAbsolute("~");
instead.
I think David, commenting on the question, is correct, but to expand on his comment:
The "~/" bit is specific to ASP.NET and won't resolve the path you'd expect. Therefore, the cookie is actually being created, but since you're setting the path to something invalid, it isn't getting returned back to you.
For example, if you set the path to "/foo", the cookie would only be returned on a request to the path /foo in your application.
Since there is no absolute path in your application equal to the literal ~/, the cookie won't be returned.
It does create a cookie. Looking in reflector, your code above is calling this:
public HttpCookie this[string name]
{
get
{
return this.Get(name);
}
}
which in turn calls:
public HttpCookie Get(string name)
{
HttpCookie cookie = (HttpCookie) base.BaseGet(name);
if ((cookie == null) && (this._response != null))
{
cookie = new HttpCookie(name);
this.AddCookie(cookie, true);
this._response.OnCookieAdd(cookie);
}
return cookie;
}
And you can see that it, in fact does, create a cookie. If you are not seeing it come back in the request, I think it has to do with your path. I am not sure "~/" is valid.
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["Font"] = "Arial";
myCookie["Color"] = "Blue";
myCookie.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(myCookie); //<<<<<<<<<-------------------
http://msdn.microsoft.com/en-us/library/78c837bd(v=VS.80).aspx