public void Login_External_Using_Correct_Credentials() { Web.Models.User loginRequest = new Web.Models.User() { IsInternalUser = false, Password = "******", UserName = "******" }; var loginResponse = _accountController.Login(loginRequest); Assert.IsNotNull(loginResponse); Assert.IsInstanceOfType(loginResponse, typeof(ViewResult)); }
public ActionResult Login() { try { string error = Request["error"]; if (!String.IsNullOrEmpty(error)) { ViewBag.ErrorMessage = Request["error_description"]; } else { string code = Request["code"]; // when we get redirected here by Forms Authentication we'll // have a ReturnUrl indicating the page we came from string returnUrl = Request.QueryString["ReturnUrl"]; if (String.IsNullOrEmpty(code)) { // CSRF protection var hashBytes = new MD5CryptoServiceProvider().ComputeHash(Guid.NewGuid().ToByteArray()); string state = Convert.ToBase64String(hashBytes); Session["state"] = state; // add the return Url to the state parameter so Facebook can send it all back to us if (!String.IsNullOrEmpty(returnUrl)) { state += returnUrl; } // good programmers encode strings before passing them to a query string state = Url.Encode(state); // don't forget to change the "scope" values listed below // to something appropriate for your facebook application // facebook warns not to get greedy as users may deny access string redirectUrl = "http://www.facebook.com/dialog/oauth?client_id=" + AppId + "&redirect_uri=" + Url.Encode(AuthorizeUrl) + "&scope=publish_stream&state=" + state; return Redirect(redirectUrl); } string sessionState = Convert.ToString(Session["state"]); string requestState = Request.QueryString["state"]; if (!String.IsNullOrEmpty(requestState) && !String.IsNullOrEmpty(sessionState) && requestState.Length >= sessionState.Length && requestState.Substring(0, sessionState.Length) == sessionState) { string tokenUrl = "https://graph.facebook.com/oauth/access_token?client_id=" + AppId + "&redirect_uri=" + Url.Encode(AuthorizeUrl) + "&client_secret=" + AppSecret + "&code=" + code; string response = GetPageContent(tokenUrl); var responseDictionary = ParseQueryString(response); if (responseDictionary.Contains("access_token")) { // note: you don't HAVE to respect this, as long as you // get a new token before trying to use the FB API double facebookTokenExpirationSeconds = Convert.ToDouble(responseDictionary["expires"]); // Note: you may want to store responseDictionary["access_token"] and // facebookTokenExpirationSeconds somewhere so you can use it for other FB API requests string graphUrl = "https://graph.facebook.com/me?access_token=" + responseDictionary["access_token"]; var serializer = new JavaScriptSerializer(); dynamic facebookUser = serializer.DeserializeObject(GetPageContent(graphUrl)); // grab facebook name and Id to use as our forms authentication ticket string facebookName = facebookUser["name"]; long facebookUserId = Convert.ToInt64(facebookUser["id"]); string facebookEmail = string.Empty; // Extended permissions try { facebookEmail = facebookUser["email"]; } catch (KeyNotFoundException exception) { LogManager.GetCurrentClassLogger() .LogException(LogLevel.Warn, "email", exception); } // Create local user if first login var user = RavenSession.Load<Web.Models.User>(facebookUserId); if (user == null) { user = new Web.Models.User() { Id = facebookUserId, Name = facebookName, Email = facebookEmail, }; // Save user to user store RavenSession.Store(user); // Notify admin about new user. TaskExecutor.ExcuteLater(new NewUserNotificationEmailTask(new NewUserRegisteredViewModel() { Id = user.Id, Name = user.Name })); } else { // Update potential name changes from fb if (facebookName != user.Name) { user.Name = facebookName; user.Email = facebookEmail; RavenSession.Store(user); } } //string userData = serializer.Serialize(facebookName); // get the cookie the way forms authentication would put it together. //Note: I am using the facebookUserId as the "username" as it's guaranteed to be unique var authCookie = FormsAuthentication.GetAuthCookie(facebookUserId.ToString(), true); var ticket = FormsAuthentication.Decrypt(authCookie.Value); // we want to change the expiration of our forms authentication cookie // to match the token expiration date, but you can also use your own expiration DateTime expiration = ticket.IssueDate.AddSeconds(facebookTokenExpirationSeconds); var newTicket = new FormsAuthenticationTicket( ticket.Version, ticket.Name, ticket.IssueDate, expiration, ticket.IsPersistent, facebookName); // encrypt the cookie again authCookie.Value = FormsAuthentication.Encrypt(newTicket); // manually set it (instead of calling FormsAuthentication.SetAuthCookie) Response.Cookies.Add(authCookie); // If we added the Redirect Url to our 'state', grab it and redirect if (requestState.Length > sessionState.Length) { returnUrl = requestState.Substring(sessionState.Length); if (!String.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } } // otherwise redirect back to Home or whatever your default page is return RedirectToAction("Index", "Items"); } else { ViewBag.ErrorMessage = "Facebook authorization replied with this invalid response: " + response; } } else { ViewBag.ErrorMessage = "There is a problem with the redirect from Facebook. You may be a victim of CSRF."; } } } catch (Exception ex) { ViewBag.ErrorMessage = "Login failed with this exception: " + ex.Message; LogManager.GetCurrentClassLogger() .FatalException("Login failed with this exception: " + ex.Message, ex); } LogManager.GetCurrentClassLogger() .Fatal("Facebook login encountered an error without a description."); ViewBag.ErrorMessage = "Facebook login encountered an error without a description."; return RedirectToAction("Index", "Home"); }