Hi my application has two types of login's one is facebook and other is normal log in. To differentiate between them and bring the values accordingly i have used cookies and clearing those in logout event like this.
But when i login through email and password and then logout and again log in through Fb the UserCookie cookie is still persisting and its entering to the first if statement again
public ActionResult Logout(string returnUrl = "/")
{
try
{
FormsAuthentication.SignOut();
}
finally
{
if (Request.Cookies["UserCookie"] != null)
{
Request.Cookies["UserCookie"].Expires = DateTime.Now;
Request.Cookies["UserCookie"].Value = "";
}
if (Request.Cookies["fbUserUserID"] != null)
{
Request.Cookies["fbUserUserID"].Expires = DateTime.Now;
Request.Cookies["fbUserUserID"].Value = "";
}
if (Request.Cookies["fbFirstName"] != null)
{
Request.Cookies["fbFirstName"].Expires = DateTime.Now;
Request.Cookies["fbFirstName"].Value = "";
}
FederatedAuthentication.WSFederationAuthenticationModule.SignOut(true);
}
//return Redirect(returnUrl);
return View();
}
and in my view i am checking for cookies like this
#if (HttpContext.Current.Request.Cookies["UserCookie"] != null && HttpContext.Current.Request.Cookies["UserCookie"].Value != "")
{
}
else if (HttpContext.Current.Request.Cookies["fbFirstName"] != null && HttpContext.Current.Request.Cookies["fbFirstName"].Value != "")
{
}
but its not clearing i guess its showing empty string "" for the cookie value in the controller but i donno whats happening in view.
is there any thing that i am missing?
Request.Cookies is used to read the cookies that have come to the server from the client. If you want to set cookies, you need to use Response.Cookies so the server sends the cookie information the server response.
Try modifying your code to use Response.Cookies instead of Request.Cookies when you are trying to unset the cookies.
Related
I am trying to implement a let's say "change my account email address" fonctionality.
I want to keep backup of all user emails in (R_EmailAddressHistory table).
Here are some of my project's code.
public bool ChangeEmailAddress(string username, string newEmailAddress, string callbackUrl)
{
DateTime currentUtcTime = DateTime.UtcNow;
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
if (currentUser.HasPendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
EmailHistoRepo.Update(currentPendingRequest);
}
else
{
currentUser.HasPendingNewEmail = true;
R_EmailAddressHistory newEmail = new R_EmailAddressHistory();
newEmail.UserId = currentUser.GId;
newEmail.R_User = currentUser;
newEmail.NewEmail = newEmailAddress;
newEmail.InsertDate = currentUtcTime;
newEmail.StatusID = (int) Reno.Common.Enums.RecordStatus.Pending;
currentUser.R_EmailAddressHistory.Add(newEmail);
}
IdentityResult idtResult = UserRepo.Update(currentUser);
if(idtResult == IdentityResult.Succeeded)
{
//Send notification to current email address for validation before proceeding change email process
bool sendResult = Communication.EmailService.SendChangeEmailValidation(username,currentUser.Email, newEmailAddress, callbackUrl);
return sendResult;
}
else
{
return false;
}
}
The previous method is use to change an email address. Each of my tables (R_User and EmailAddressHistory ) has Repository (UserRepo and EmailHistoRepo). The implement the same IRepositoryBase class, here is the Update methode
public IdentityResult Update(T entity)
{
try
{
if (_currentContext.DbContext.Entry(entity).State == EntityState.Detached)
{
_currentContext.DbContext.Set<T>().Attach(entity);
}
_currentContext.DbContext.Entry(entity).State = EntityState.Modified;
return IdentityResult.Succeeded;
}
catch
{
return IdentityResult.Failed;
}
}
When a user has already a non validate new email address, when he request to change his current email address, I show him the pending new email address and he can change it, in this case I whant to update my historical table instead of creating a new one, cause only one pending new email address is allow. In such a case, my code failed in the line EmailHistoRepo.Update(currentPendingRequest) throwing the error : An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Can anyone help me?
Thanks
EDIT
I am using MVC(4) with a unitOfWork. My UOW is initialized in a the Controller the first time the DB is queried and the Commit is done in the global.asax file in Appalication_EndRequest (see below).
protected void Application_EndRequest(Object sender, EventArgs e)
{
CommitChanges();
}
private void CommitChanges()
{
Reno.BLL.Services.Singleton.UnitOfWork unitOfWork = Reno.BLL.Services.Singleton.UnitOfWork.GetCurrentInstance(false);
if (unitOfWork != null)
{
unitOfWork.Commit();
unitOfWork.Dispose();
}
}
Your currentUser is modified before updating the emailaddress. Save the changes to currentUser first.
Something like this:
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
bool pendingNewEmail = currentUser.HasPendingNewEmail;
UserRepo.Update(currentUser);
if (pendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
EmailHistoRepo.Update(currentPendingRequest);
}
else
I finally found the answer. The problem was that when I first get the user in line
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
The currentUser variable hold a refrence of all of its R_EmailAddressHistory.
And then after, I queried the DB (2nd time) to get the pending email change request (or type R_EmailAddressHistory) to modify its new email and its update date, in line
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
But te last code updates only currentPendingRequest while another reference of the same object which is in currentUser.R_EmailAddressHistory is not update and was already tracked by the context. Therefore, by doing an update on the new instance (EmailHistoRepo.Update(currentPendingRequest)), the code failed: the same object if referenced in 2 places.
So, the solution was (the only thing I modified):
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
if (currentUser.HasPendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = currentUser.R_EmailAddressHistory.Where(h => h.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending).First(); // EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
}
I decided to modify the instance in currentUser variable.
I'm new to web api and I seem to be having an issue with getting the name of the signed in user inside of my post method. Im using
RequestContext.Principal.Identity.Name
However, this only seems to be returning an empty string. It works fine in my get method, but not in the post. Here's my entire method
[Route("receive")]
[HttpPost]
public HttpResponseMessage Receive(PostmarkInboundMessage message)
{
if (message != null)
{
// To access message data
var headers = message.Headers ?? new List<Header>();
// To access Attachments
if (message.Attachments != null)
{
var attachments = message.Attachments;
var c = new CVService();
var user = string.IsNullOrEmpty(RequestContext.Principal.Identity.Name) ? "unknown" : RequestContext.Principal.Identity.Name;
c.UpdateLog(user);
foreach (var attachment in attachments)
{
// Access normal members, etc
var attachmentName = attachment.Name;
// To access file data and save to c:\temp\
//if (Convert.ToInt32(attachment.ContentLength) > 0)
//{
// byte[] filebytes = Convert.FromBase64String(attachment.Content);
// var fs = new FileStream(attachmentSaveFolder + attachment.Name,
// FileMode.CreateNew,
// FileAccess.Write,
// FileShare.None);
// fs.Write(filebytes, 0, filebytes.Length);
// fs.Close();
//}
}
}
// If we succesfully received a hook, let the call know
return new HttpResponseMessage(HttpStatusCode.Created); // 201 Created
}
else
{
// If our message was null, we throw an exception
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent("Error parsing Inbound Message.") });
}
}
Any help will be greatly appreciated.
Be sure you send the header (token) in both methods GET and POST and also, set the [Authorize] filter in both methods or the controller itself so you will be rejected if the token is not being send
I am trying generate a password manually to insert it directly into the database. But unfortunatelly I doesn´t work.
Spring security core is set to use MD5 encoding. I generate a new password in a md5 hash generation webpage, update the bbdd but I can not log in with that user.
I guess it has some specific structure before enconding but I don´t know it.
Just have a look in the source code of the basespasswordencoder class.
protected String mergePasswordAndSalt(String password, Object salt, boolean strict) {
if (password == null) {
password = "";
}
if (strict && (salt != null)) {
if ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1)) {
throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
}
}
if ((salt == null) || "".equals(salt)) {
**return password**;
} else {
**return password + "{" + salt.toString() + "}"**;
}
}
}
http://grepcode.com/file/repo1.maven.org/maven2/org.springframework.security/spring-security-core/3.0.1.RELEASE/org/springframework/security/authentication/encoding/BasePasswordEncoder.java#BasePasswordEncoder.mergePasswordAndSalt%28java.lang.String%2Cjava.lang.Object%2Cboolean%29
I have a login page (username,password fields) that has a checkbox 'Remember me'. If the checkbox is selected, the application is required to remember the username & password for next login. That is done and working fine. However I am finding it hard to save the state of the checkbox field, i.e. whether it is checked or not. I am saving the username/password through the following code:
if (persistentObject.getContents() == null)
{
persistentHashtable = new Hashtable();
persistentObject.setContents(persistentHashtable);
} else {
persistentHashtable = (Hashtable) persistentObject.getContents();
}
if (persistentHashtable.containsKey("username") && persistentHashtable.containsKey("password"))
{
username.setText((String) persistentHashtable.get("username"));
passwd.setText((String) persistentHashtable.get("password"));
}
If the checkbox is selected and login is successfull, username and password are saved through the following:
if(checkBox1.getChecked() == true)
{
persistentHashtable.put("username", user_id);
persistentHashtable.put("password", password);
}
I tried to save the checkbox state with the line below but that is incorrect.
persistentHashtable.put("checkbox", checkBox1.setChecked(true));
Can somebody please help?
RIM rapc.exe compiler does not support autoboxing (it works in java 1.3 compatibility mode), and then you need to wrap your boolean value to a Boolean class instance before saving it in a hashtable or passing it to persistent store.
Hey guys I managed to find a solution to my problem. I worked around by checking if the username field is empty, then the checkbox state should be 'unchecked' else it should be 'checked'. This is doing what I wanted. If anyone of you have a better way of doing this please do suggest. My working line of code is as below:
if(username.getText().length()==0)
{
checkBox1 = new CheckboxField("Remember me",false);
}
else
{
checkBox1 = new CheckboxField("Remember me",true);
}
false = unchecked , true = checked
Check box is used for user wishes , according to your code , If user have entered user name checkbox will be checked.
Your Code is bit complex , First you need to setcontent code to persistent in very last , once you set your hashtable . You are having a login screen so you must have a submit button.
Do like this on submit button event:
// to set persistent values
if(checkBox1.getChecked() == true)
{
persistentHashtable = new Hashtable();
persistentHashtable.put("username", user_id);
persistentHashtable.put("password", password);
persistentHashtable.put("checkbox", "true");
persistentObject.setContents(persistentHashtable);
persistentObject.commit() ;
}
// to get from persistent values
if (persistentObject.getContents() != null)
{
persistentHashtable = (Hashtable) persistentObject.getContents();
username.setText((String) persistentHashtable.get("username"));
passwd.setText((String) persistentHashtable.get("password"));
String boolval = (String) persistentHashtable.get("checkbox");
if(boolval.equals("true"))
checkBox1 = new CheckboxField("Remember me",true);
else
checkBox1 = new CheckboxField("Remember me",false);
}
I implemented Facebook-Connect successfully and I'm able to retrieve User-Information using the Facebook Toolkit. But I cant sucessfully logout.
When I press the facebook-Logout button (which automatically appears when I'm logged in, because I'm using the autologoutlink-property)
<fb:login-button autologoutlink="true"></fb:login-button>
I still have all five Facebook-Cookies:
MyApiKey
MyApiKey_ss
MyApiKey_SessionKey
MyApiKey_expires
MyApiKey_user
After I'm logged out, I'm really logged out in Facebook, because I need to login again at facebook.com but isConnected() always returns true and I can still retrieve the user Information:
var connectSession = new ConnectSession(ConfigurationManager.AppSettings["ApiKey"], ConfigurationManager.AppSettings["Secret"]);
if (connectSession.IsConnected())
{
var api = new Api(connectSession);
filterContext.Controller.ViewData["FBUser"] = api.Users.GetInfo();
}
First I don't understand why I can still retrieve User Information even though I'm not logged in any more, and secondly: How I can delete this Cookies. The Following Code didn't work:
public static void ClearFacebookCookies()
{
String[] shortNames = new String[] { "_user", "_session_key", "_expires", "_ss", "" };
HttpContext currentContext = HttpContext.Current;
if (currentContext == null)
{
return;
}
string appKey = ConfigurationManager.AppSettings["APIKey"];
if (appKey == null)
{
throw new Exception("APIKey is not defined in web.config");
}
foreach (var name in shortNames)
{
string fullName = appKey + name;
HttpCookie cookie = currentContext.Response.Cookies[fullName];
if (cookie != null)
{
cookie.Value = null;
cookie.Expires= DateTime.Now.AddDays(-1d);
}
HttpCookie cookieRequest = currentContext.Request.Cookies[fullName];
if (cookieRequest != null)
{
cookieRequest.Value = null;
cookieRequest.Expires = DateTime.Now.AddDays(-1d);
}
}
}// end Method
This may be a shot in the dark, but did you make sure the fb.init is placed just before the closing body tag?
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"></script>
<script type="text/javascript">FB.init('somekey');</script>
That's caused me problems before.