Пример #1
0
        public async Task <IActionResult> Login(ApplicationUser user, string returnUrl = null)
        {
            var use_sams = false;

            if (!string.IsNullOrWhiteSpace(_configuration["sams:is_enabled"]))
            {
                bool.TryParse(_configuration["sams:is_enabled"], out use_sams);
            }

            if (use_sams)
            {
                return(RedirectToAction("SignIn"));
            }

            const string badUserNameOrPasswordMessage = "Username or password is incorrect.";

            if (
                user == null ||
                string.IsNullOrWhiteSpace(user.UserName) ||
                string.IsNullOrWhiteSpace(user.Password)
                )
            {
                return(BadRequest(badUserNameOrPasswordMessage));
            }



            try
            {
                var unsuccessful_login_attempts_number_before_lockout     = Program.config_unsuccessful_login_attempts_number_before_lockout;
                var unsuccessful_login_attempts_within_number_of_minutes  = Program.config_unsuccessful_login_attempts_within_number_of_minutes;
                var unsuccessful_login_attempts_lockout_number_of_minutes = Program.config_unsuccessful_login_attempts_lockout_number_of_minutes;
                var password_days_before_expires = Program.config_password_days_before_expires;


                var is_locked_out      = false;
                var failed_login_count = 0;


                DateTime grace_period_date = DateTime.Now;

                try
                {
                    //var session_event_request_url = $"{Program.config_couchdb_url}/session/_design/session_event_sortable/_view/by_date_created_user_id?startkey=[" + "{}" + $",\"{user.UserName}\"]&decending=true&limit={unsuccessful_login_attempts_number_before_lockout}";
                    var session_event_request_url = $"{Program.config_couchdb_url}/session/_design/session_event_sortable/_view/by_user_id?startkey=\"{user.UserName}\"&endkey=\"{user.UserName}\"";

                    var    session_event_curl   = new cURL("GET", null, session_event_request_url, null, Program.config_timer_user_name, Program.config_timer_password);
                    string response_from_server = await session_event_curl.executeAsync();

                    //var session_event_response = Newtonsoft.Json.JsonConvert.DeserializeObject<mmria.common.model.couchdb.get_sortable_view_reponse_object_key_header<mmria.common.model.couchdb.session_event>>(response_from_server);
                    var session_event_response = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.get_sortable_view_reponse_header <mmria.common.model.couchdb.session_event> >(response_from_server);

                    DateTime first_item_date = DateTime.Now;
                    DateTime last_item_date  = DateTime.Now;


                    var MaxRange = DateTime.Now.AddMinutes(-unsuccessful_login_attempts_within_number_of_minutes);
                    session_event_response.rows.Sort(new mmria.common.model.couchdb.Compare_Session_Event_By_DateCreated <mmria.common.model.couchdb.session_event>());

/*
 *                  if(password_days_before_expires > 0)
 *                  {
 *                      var date_of_last_password_change = DateTime.MinValue;
 *
 *                      foreach(var session_event in session_event_response.rows)
 *                      {
 *                          if(session_event.value.action_result == mmria.common.model.couchdb.session_event.session_event_action_enum.password_changed)
 *                          {
 *                              date_of_last_password_change = session_event.value.date_created;
 *                              break;
 *                          }
 *                      }
 *
 *                      if(date_of_last_password_change != DateTime.MinValue)
 *                      {
 *                          days_til_password_expires = password_days_before_expires - (int)(DateTime.Now - date_of_last_password_change).TotalDays;
 *                      }
 *                  }
 */

                    foreach (var session_event in session_event_response.rows.Where(row => row.value.date_created >= MaxRange))
                    {
                        if (session_event.value.action_result == mmria.common.model.couchdb.session_event.session_event_action_enum.failed_login)
                        {
                            failed_login_count++;
                            if (failed_login_count == 1)
                            {
                                first_item_date = session_event.value.date_created;
                            }

                            if (failed_login_count >= unsuccessful_login_attempts_number_before_lockout)
                            {
                                last_item_date    = session_event.value.date_created;
                                grace_period_date = first_item_date.AddMinutes(unsuccessful_login_attempts_lockout_number_of_minutes);
                                if (DateTime.Now < grace_period_date)
                                {
                                    is_locked_out = true;
                                    break;
                                }
                            }
                        }
                        else if (session_event.value.action_result == mmria.common.model.couchdb.session_event.session_event_action_enum.successful_login)
                        {
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Console.WriteLine($"{ex}");
                }


                if (is_locked_out)
                {
                    return(RedirectToAction("Locked", new { user_name = user.UserName, grace_period_date = grace_period_date }));
                    //return View("~/Views/Account/Locked.cshtml");
                }


                string post_data       = string.Format("name={0}&password={1}", user.UserName, user.Password);
                byte[] post_byte_array = System.Text.Encoding.ASCII.GetBytes(post_data);

                string request_string         = Program.config_couchdb_url + "/_session";
                System.Net.WebRequest request = System.Net.WebRequest.Create(new Uri(request_string));
                //request.UseDefaultCredentials = true;

                request.PreAuthenticate = false;
                //request.Credentials = new System.Net.NetworkCredential("mmrds", "mmrds");
                request.Method        = "POST";
                request.ContentType   = "application/x-www-form-urlencoded";
                request.ContentLength = post_byte_array.Length;

                using (System.IO.Stream stream = request.GetRequestStream())
                {
                    stream.Write(post_byte_array, 0, post_byte_array.Length);
                }

                System.Net.WebResponse response   = (System.Net.HttpWebResponse)request.GetResponse();
                System.IO.Stream       dataStream = response.GetResponseStream();
                System.IO.StreamReader reader     = new System.IO.StreamReader(dataStream);
                string responseFromServer         = await reader.ReadToEndAsync();

                mmria.common.model.couchdb.login_response json_result = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.login_response>(responseFromServer);

                mmria.common.model.couchdb.login_response[] result = new mmria.common.model.couchdb.login_response[]
                {
                    json_result
                };


                this.Response.Headers.Add("Set-Cookie", response.Headers["Set-Cookie"]);

                string[] set_cookie = response.Headers["Set-Cookie"].Split(';');
                string[] auth_array = set_cookie[0].Split('=');
                if (auth_array.Length > 1)
                {
                    string auth_session_token = auth_array[1];
                    result[0].auth_session = auth_session_token;
                }
                else
                {
                    result[0].auth_session = "";
                }


                if (json_result.ok && !string.IsNullOrWhiteSpace(json_result.name))
                {
                    const string Issuer = "https://contoso.com";
                    var          claims = new List <Claim>();
                    claims.Add(new Claim(ClaimTypes.Name, json_result.name, ClaimValueTypes.String, Issuer));


                    foreach (var role in json_result.roles)
                    {
                        if (role == "_admin")
                        {
                            claims.Add(new Claim(ClaimTypes.Role, "installation_admin", ClaimValueTypes.String, Issuer));
                        }
                    }


                    foreach (var role in mmria.server.util.authorization.get_current_user_role_jurisdiction_set_for(json_result.name).Select(jr => jr.role_name).Distinct())
                    {
                        claims.Add(new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, Issuer));
                    }


                    //Response.Cookies.Append("uid", json_result.name);
                    //Response.Cookies.Append("roles", string.Join(",",json_result.roles));

                    //claims.Add(new Claim("EmployeeId", string.Empty, ClaimValueTypes.String, Issuer));
                    //claims.Add(new Claim("EmployeeId", "123", ClaimValueTypes.String, Issuer));
                    //claims.Add(new Claim(ClaimTypes.DateOfBirth, "1970-06-08", ClaimValueTypes.Date));
                    //var userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

                    var session_idle_timeout_minutes = 30;

                    if (_configuration["mmria_settings:session_idle_timeout_minutes"] != null)
                    {
                        int.TryParse(_configuration["mmria_settings:session_idle_timeout_minutes"], out session_idle_timeout_minutes);
                    }

                    var userIdentity = new ClaimsIdentity("SuperSecureLogin");
                    userIdentity.AddClaims(claims);
                    var userPrincipal = new ClaimsPrincipal(userIdentity);

                    await HttpContext.SignInAsync(
                        CookieAuthenticationDefaults.AuthenticationScheme,
                        userPrincipal,
                        new AuthenticationProperties
                    {
                        ExpiresUtc   = DateTime.UtcNow.AddMinutes(session_idle_timeout_minutes),
                        IsPersistent = false,
                        AllowRefresh = false,
                    });
                }

                var Session_Event_Message = new mmria.server.model.actor.Session_Event_Message
                                            (
                    DateTime.Now,
                    user.UserName,
                    this.GetRequestIP(),
                    json_result.ok && json_result.name != null? mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.successful_login: mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.failed_login
                                            );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Record_Session_Event>()).Tell(Session_Event_Message);

                //this.ActionContext.Response.Headers.Add("Set-Cookie", auth_session_token);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                var Session_Event_Message = new mmria.server.model.actor.Session_Event_Message
                                            (
                    DateTime.Now,
                    user.UserName,
                    this.GetRequestIP(),
                    mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.failed_login
                                            );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Record_Session_Event>()).Tell(Session_Event_Message);
            }

/*
 *          var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
 *          identity.AddClaim(new Claim(ClaimTypes.Name, lookupUser.UserName));
 *
 *          await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
 */
            if (returnUrl == null)
            {
                returnUrl = TempData["returnUrl"]?.ToString();
            }

            if (returnUrl != null)
            {
                return(Redirect(returnUrl));
            }

            return(RedirectToAction(nameof(HomeController.Index), "Home"));
        }
Пример #2
0
        public async Task <ActionResult> SignInCallback()
        {
            var sams_endpoint_authorization    = _configuration["sams:endpoint_authorization"];
            var sams_endpoint_token            = _configuration["sams:endpoint_token"];
            var sams_endpoint_user_info        = _configuration["sams:endpoint_user_info"];
            var sams_endpoint_token_validation = _configuration["sams:token_validation"];
            var sams_endpoint_user_info_sys    = _configuration["sams:endpoint_user_info_sys"];
            var sams_client_id     = _configuration["sams:client_id"];
            var sams_client_secret = _configuration["sams:client_secret"];

            var sams_callback_url = _configuration["sams:callback_url"];

            //?code=6c17b2a3-d65a-44fd-a28c-9aee982f80be&state=a4c8326ca5574999aa13ca02e9384c3d
            // Retrieve code and state from query string, pring for debugging
            var querystring       = Request.QueryString.Value;
            var querystring_skip  = querystring.Substring(1, querystring.Length - 1);
            var querystring_array = querystring_skip.Split("&");

            var querystring_dictionary = new Dictionary <string, string>();

            foreach (string item in querystring_array)
            {
                var pair = item.Split("=");
                querystring_dictionary.Add(pair[0], pair[1]);
            }

            var code  = querystring_dictionary["code"];
            var state = querystring_dictionary["state"];

            System.Diagnostics.Debug.WriteLine($"code: {code}");
            System.Diagnostics.Debug.WriteLine($"state: {state}");

            HttpClient client  = new HttpClient();
            var        request = new HttpRequestMessage(HttpMethod.Post, sams_endpoint_token);

            /*
             * request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
             *  { "client_id", sams_client_id },
             *  { "client_secret", sams_client_secret },
             *  { "grant_type", "client_credentials" },
             *  { "code", code },
             * });
             */

            request.Content = new FormUrlEncodedContent(new Dictionary <string, string> {
                { "client_id", sams_client_id },
                { "client_secret", sams_client_secret },
                { "grant_type", "authorization_code" },
                { "code", code },
                { "scope", "openid profile email" },
                { "redirect_uri", sams_callback_url }
            });


            var response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();

            var payload       = JObject.Parse(await response.Content.ReadAsStringAsync());
            var access_token  = payload.Value <string>("access_token");
            var refresh_token = payload.Value <string>("refresh_token");
            var expires_in    = payload.Value <int>("expires_in");


            var scope = payload.Value <string>("scope");

            //HttpContext.Session.SetString("access_token", access_token);
            //HttpContext.Session.SetString("refresh_token", refresh_token);

            var unix_time = DateTimeOffset.UtcNow.AddSeconds(expires_in);
            //HttpContext.Session.SetString("expires_at", unix_time.ToString());



            var id_token = payload.Value <string>("id_token");;
            var id_array = id_token.Split('.');


            var replaced_value = id_array[1].Replace('-', '+').Replace('_', '/');
            var base64         = replaced_value.PadRight(replaced_value.Length + (4 - replaced_value.Length % 4) % 4, '=');


            var id_0 = DecodeToken(id_array[0]);
            var id_1 = DecodeToken(id_array[1]);

            var id_body = Base64Decode(base64);

            var user_info_sys_request = new HttpRequestMessage(HttpMethod.Post, sams_endpoint_user_info + "?token=" + id_token);


            user_info_sys_request.Headers.Add("Authorization", "Bearer " + access_token);
            user_info_sys_request.Headers.Add("client_id", sams_client_id);
            user_info_sys_request.Headers.Add("client_secret", sams_client_secret);

            /*
             * user_info_sys_request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
             *  { "client_id", sams_client_id },
             *  { "client_secret", sams_client_secret },
             *  { "grant_type", "client_credentials" },
             *  { "scope", scope },
             * });
             */



            response = await client.SendAsync(user_info_sys_request);

            response.EnsureSuccessStatusCode();

            var temp_string = await response.Content.ReadAsStringAsync();

            payload = JObject.Parse(temp_string);


            var email = payload.Value <string>("email");


            //check if user exists
            var config_couchdb_url     = _configuration["mmria_settings:couchdb_url"];
            var config_timer_user_name = _configuration["mmria_settings:timer_user_name"];
            var config_timer_password  = _configuration["mmria_settings:timer_password"];

            mmria.common.model.couchdb.user user = null;
            try
            {
                string request_string     = config_couchdb_url + "/_users/" + System.Web.HttpUtility.HtmlEncode("org.couchdb.user:"******"GET", null, request_string, null, config_timer_user_name, config_timer_password);
                var    responseFromServer = await user_curl.executeAsync();

                user = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.user>(responseFromServer);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            mmria.common.model.couchdb.document_put_response user_save_result = null;

            if (user == null)// if user does NOT exists create user with email
            {
                user = add_new_user(email.ToLower(), Guid.NewGuid().ToString());

                try
                {
                    Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings();
                    settings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                    var object_string = Newtonsoft.Json.JsonConvert.SerializeObject(user, settings);

                    string user_db_url = config_couchdb_url + "/_users/" + user._id;

                    var user_curl          = new mmria.server.cURL("PUT", null, user_db_url, object_string, config_timer_user_name, config_timer_password);
                    var responseFromServer = await user_curl.executeAsync();

                    user_save_result = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.document_put_response>(responseFromServer);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

            //create login session
            if (user_save_result == null || user_save_result.ok)
            {
                var session_data = new System.Collections.Generic.Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
                session_data["access_token"]  = access_token;
                session_data["refresh_token"] = refresh_token;
                session_data["expires_at"]    = unix_time.ToString();

                await create_user_principal(user.name, new List <string>(), unix_time.DateTime);


                var Session_Event_Message = new mmria.server.model.actor.Session_Event_Message
                                            (
                    DateTime.Now,
                    user.name,
                    this.GetRequestIP(),
                    mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.successful_login
                                            );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Record_Session_Event>()).Tell(Session_Event_Message);



                var Session_Message = new mmria.server.model.actor.Session_Message
                                      (
                    Guid.NewGuid().ToString(), //_id =
                    null,                      //_rev =
                    DateTime.Now,              //date_created =
                    DateTime.Now,              //date_last_updated =
                    null,                      //date_expired =

                    true,                      //is_active =
                    user.name,                 //user_id =
                    this.GetRequestIP(),       //ip =
                    Session_Event_Message._id, // session_event_id =
                    session_data
                                      );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Post_Session>()).Tell(Session_Message);
                Response.Cookies.Append("sid", Session_Message._id);
                Response.Cookies.Append("expires_at", unix_time.ToString());
                //return RedirectToAction("Index", "HOME");
                //return RedirectToAction("Index", "HOME");
            }

            return(RedirectToAction("Index", "HOME"));

            // Generate JWT for token request
            //var cert = new X509Certificate2(Server.MapPath("~/App_Data/cert.pfx"), "1234");

            /*
             * var cert = new X509Certificate2();
             * var signingCredentials = new SigningCredentials(new X509SecurityKey(cert), SecurityAlgorithms.RsaSha256);
             * var header = new JwtHeader(signingCredentials);
             *
             * var header = new JwtHeader();
             * var payload = new JwtPayload
             * {
             *  {"iss", sams_client_id},
             *  {"sub", sams_client_id},
             *  {"aud", $"{sams_endpoint_token}"},
             *  {"jti", Guid.NewGuid().ToString("N")},
             *  {"exp", (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds + 5 * 60}
             * };
             * var securityToken = new JwtSecurityToken(header, payload);
             * var handler = new JwtSecurityTokenHandler();
             * var tokenString = handler.WriteToken(securityToken);
             *
             * // Send POST to make token request
             * using (var wb = new WebClient())
             * {
             *  var data = new NameValueCollection();
             *  data["client_assertion"] = tokenString;
             *  data["client_assertion_type"] = HttpUtility.HtmlEncode("urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
             *  data["code"] = code;
             *  data["grant_type"] = "authorization_code";
             *
             *  //var response = wb.UploadValues($"{IdpUrl}/api/openid_connect/token", "POST", data);
             *  var response = wb.UploadValues($"{sams_endpoint_token}", "POST", data);
             *
             *  var responseString = Encoding.ASCII.GetString(response);
             *  dynamic tokenResponse = JObject.Parse(responseString);
             *
             *  var token = handler.ReadToken((String)tokenResponse.id_token) as JwtSecurityToken;
             *  var userId = token.Claims.First(c => c.Type == "sub").Value;
             *  var userEmail = token.Claims.First(c => c.Type == "email").Value;
             *
             *  TempData["id"] = userId;
             *  TempData["email"] = userEmail;
             *  //return RedirectToAction("Index", "HOME");
             *  return RedirectToAction("Index", "HOME");
             * }*/
        }
Пример #3
0
        public async System.Threading.Tasks.Task <mmria.common.model.couchdb.document_put_response> Post([FromBody] ApplicationUser user)
        {
            //bool valid_login = false;

            string object_string = null;

            mmria.common.model.couchdb.document_put_response result = new mmria.common.model.couchdb.document_put_response();

            var userName = User.Identities.First(
                u => u.IsAuthenticated &&
                u.HasClaim(c => c.Type == ClaimTypes.Name)).FindFirst(ClaimTypes.Name).Value;

/* */



            try
            {
                string user_db_url        = Program.config_couchdb_url + "/_users/org.couchdb.user:"******"GET", null, user_db_url, object_string, Program.config_timer_user_name, Program.config_timer_password);
                var    responseFromServer = await user_curl.executeAsync();

                var user_object = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.user>(responseFromServer);

                if
                (
                    user_object == null ||
                    !user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase)
                )
                {
                    return(null);
                }

                user_object.password = user.Password;

                Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings();
                settings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                object_string = Newtonsoft.Json.JsonConvert.SerializeObject(user_object, settings);

                user_curl          = new cURL("PUT", null, user_db_url, object_string, Program.config_timer_user_name, Program.config_timer_password);
                responseFromServer = await user_curl.executeAsync();

                result = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.document_put_response>(responseFromServer);

                if (result.ok)
                {
                    var Session_Event_Message = new mmria.server.model.actor.Session_Event_Message
                                                (
                        DateTime.Now,
                        userName,
                        _accessor.HttpContext.Connection.RemoteIpAddress.ToString(),
                        mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.password_changed
                                                );

                    _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Record_Session_Event>()).Tell(Session_Event_Message);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return(result);
        }