using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Web; using BeWo.Data.Access; using BeWo.Data.Entities; using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using log4net.Config; using NHibernate; using NHibernate.Cfg; namespace BeWo.Data { public class ASPHibernateSessionManager : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.AcquireRequestState += (s, e) => { Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); if (ShouldConfigureHibernateSession(context)) { // TEST FOR DEVEXPRESS. PROBLEMS WITH THIS MODULE WHEN USING AJAX! if (HttpContext.Current.Session == null) { return; } // --------------------------------------------------------------- if (!ConfigureHibernateSession(context)) { return; } // throw new Exception("Could not configure database. No tenant parameter found"); var userLoaded = TryAuthenticateWithRequestParams(context); if (!userLoaded) { userLoaded = TryAuthenticateWithLoginForm(context); } if (!userLoaded) { userLoaded = TryAuthenticateWithGkv(context); } //if (!userLoaded && !(SessionFacade.LoggedInUserDC?.UserOid is null)) //{ // SessionFacade.LoggedInUserDC = CreateUserDC(DAOFactory.GenericDAO.LoadByID(SessionFacade.LoggedInUser.Oid.Value)); //} } }; context.EndRequest += (s, e) => { if (HttpContext.Current.Items["hibernateSession"] != null) { ((ISession)HttpContext.Current.Items["hibernateSession"]).Close(); } }; } private static bool ShouldConfigureHibernateSession(HttpApplication context) { if (string.IsNullOrEmpty(context.Request.FilePath)) return false; if (context.Request.FilePath.IndexOf("GkvAbrechnungServer.aspx") >= 0) return false; if (context.Request.FilePath.IndexOf("Admin.aspx") >= 0) return false; return true; } private static bool ConfigureHibernateSession(HttpApplication context) { var lTenant = GetTenant(context); if (!string.IsNullOrEmpty(lTenant)) { SessionFacade.Tenant = lTenant; } else { lTenant = SessionFacade.Tenant; } if (string.IsNullOrEmpty(lTenant)) { return false; } var sessionFactory = new Configuration().Configure(context.Server.MapPath(@"Multitenancy\" + lTenant + ".config")).BuildSessionFactory(); XmlConfigurator.Configure(); if (HttpContext.Current.Items.Contains("hibernateSession")) { HttpContext.Current.Items.Remove("hibernateSession"); } HttpContext.Current.Items.Add("hibernateSession", sessionFactory.OpenSession()); return true; } private static String GetTenant(HttpApplication context) { var lTenant = String.Empty; String token = context.Request.Params["token"]; if (!String.IsNullOrEmpty(token)) lTenant = GetLoginInfoFromToken(token)["tenant"]; if (String.IsNullOrEmpty(lTenant)) lTenant = context.Request.Params["tenant"]; if (String.IsNullOrEmpty(lTenant)) lTenant = context.Request.Params["knr"]; if (String.IsNullOrEmpty(lTenant)) lTenant = context.Request.Params["kunde"]; if (String.IsNullOrEmpty(lTenant)) lTenant = context.Request.Params["k"]; return lTenant; } private static bool TryAuthenticateWithRequestParams(HttpApplication context) { string lUserName = null; string lPassword = null; //if (!context.Request.Params.AllKeys.Contains("tenant")) // return false; var lTenant = GetTenant(context); if (!string.IsNullOrEmpty(lTenant)) { if (context.Request.Params.AllKeys.Contains("token")) { lUserName = GetLoginInfoFromToken(context.Request.Params["token"])["user"]; lPassword = GetLoginInfoFromToken(context.Request.Params["token"])["password"]; } } else { lUserName = context.Request.Params["username"]; lPassword = context.Request.Params["token"]; } if (!BS.Shared.Core.Utils.IsAnyNullOrEmpty(lUserName, lPassword)) { var ip = context.Request.UserHostAddress; var lUser = DAOFactory.UserDAO.FindUserByLoginName(lUserName, ip); if (lUser != null && lUser.CheckRC2Password(lPassword)) { SessionFacade.LoggedInUserOid = lUser.Oid; return true; } } return false; } private static bool TryAuthenticateWithLoginForm(HttpApplication context) { var name = context.Request.Params["ctl00$tb_login"]; var password = context.Request.Params["ctl00$tb_password"]; if (!BS.Shared.Core.Utils.IsAnyNullOrEmpty(name, password)) { ApplicationUser user = DAOFactory.UserDAO.FindUserByLoginName(name); if (user != null && DAOFactory.UserDAO.CheckPassword(user, password)) { SessionFacade.LoggedInUserOid = user.Oid; return true; } } return false; } private static bool TryAuthenticateWithGkv(HttpApplication context) { if (context.Request.FilePath.IndexOf("GkvAbrechnungClient.aspx") == -1) return false; if (!IsRequestIPValid("App8IpAddress")) return false; var useroidstr = context.Request.Params["useroid"]; if (!long.TryParse(useroidstr, out long useroid)) return false; SessionFacade.LoggedInUserOid = useroid; return true; } public static bool IsRequestIPValid(string appsetting) { var clientip = GetRequestIP(true); var appsettingip = System.Configuration.ConfigurationManager.AppSettings[appsetting]; #if DEBUG if (clientip == "::1") return true; #endif return clientip == appsettingip; } private static string GetRequestIP(bool CheckForward = false) { // https://stackoverflow.com/a/13249280 string ip = null; if (CheckForward) { ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; } if (string.IsNullOrEmpty(ip)) { ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } else { // Using X-Forwarded-For last address ip = ip.Split(',') .Last() .Trim(); } return ip; } private static Dictionary GetLoginInfoFromToken(string token) { if (string.IsNullOrWhiteSpace(token)) { return new Dictionary(); } string decodedToken; token = token.Replace(' ', '+'); token = token.Trim(','); try { decodedToken = DecryptString(HttpUtility.UrlDecode(token)); } catch (Exception) { decodedToken = DecryptString(token); } if (decodedToken.Split(';')[2].Split('=')[0].Equals("myToken")) { var b = decodedToken.Split(';'); var a = DecryptString(new Regex(@"[\=]{1}").Split(b[2], 2)[1]); decodedToken += ";" + a; } var Params = decodedToken.Split(';'); return Params.Select(item => item.Split('=')).Where(a => a[0].Equals("tenant") || a[0].Equals("password") || a[0].Equals("user")).ToDictionary(a => a[0], a => a[1]); } private static string DecryptString(string strToDecrypt) { if (string.IsNullOrWhiteSpace(strToDecrypt)) { return "Beim Decodieren ist leider ein Fehler aufgetreten."; } strToDecrypt = strToDecrypt.Replace(' ', '+'); if (strToDecrypt.Contains(",")) { strToDecrypt = strToDecrypt.Split(',')[0]; } byte[] _Rc2IV = { 35, 138, 177, 253, 227, 63, 2, 27 }; byte[] _Rc2Key = { 174, 130, 219, 185, 185, 221, 96, 50, 37, 212, 81, 121, 71, 206, 130, 153 }; var lRc2CSP = new RC2CryptoServiceProvider(); var lDecryptor = lRc2CSP.CreateDecryptor(_Rc2Key, _Rc2IV); strToDecrypt = strToDecrypt.Replace(' ', '+'); strToDecrypt = strToDecrypt.Trim(','); using (var msDecrypt = new MemoryStream(Convert.FromBase64String(strToDecrypt))) { using (var csDecrypt = new CryptoStream(msDecrypt, lDecryptor, CryptoStreamMode.Read)) { var bytes = new List(); int b; do { b = csDecrypt.ReadByte(); if (b != -1) { bytes.Add(Convert.ToByte(b)); } } while (b != -1); return Encoding.UTF8.GetString(bytes.ToArray()); } } } private static UserDC CreateUserDC(ApplicationUser pEntity) { var pDataContract = new UserDC(); pDataContract.UserOid = pEntity.Oid; pDataContract.UserVersion = pEntity.Version; pDataContract.LoginName = pEntity.LoginName; pDataContract.Zeitstempel = pEntity.Zeitstempel ?? DateTime.Now; pDataContract.LicenseType = pEntity.LicenseType; if (pEntity.Employee != null) { pDataContract.Employee = CreateCompactEmployeeDC(pEntity.Employee); } pDataContract.UserGroups = CreateUserGroupDcList(pEntity.UserGroups); pDataContract.Settings = CreateSettingDcList(pEntity.SettingList); return pDataContract; } private static CompactEmployeeDC CreateCompactEmployeeDC(Employee pEntity) { var pDataContract = new CompactEmployeeDC(); pDataContract.EmployeeOid = pEntity.Oid.Value; pDataContract.PersonOid = pEntity.Person.Oid.Value; pDataContract.EmployeeVersion = pEntity.Version.Value; pDataContract.FirstName = pEntity.Person.FirstName; pDataContract.LastName = pEntity.Person.LastName; pDataContract.PersonnelNumber = pEntity.PersonnelNumber; pDataContract.ActivationType = pEntity.IsActive; pDataContract.ValueListEntries = pEntity.ValueList.ToDictionary(i => i.Entry.Oid.Value, i => i.Entry.Type); pDataContract.EmployeeColor = pEntity.EmployeeColor; pDataContract.RelatedCustomerOIDList = pEntity.Employee2CustomerList.Where(w => w.CustomerOid.HasValue).Select(s => s.CustomerOid.Value).ToList(); return pDataContract; } private static UserGroupDC MergeWithDC(UserGroup pEntity, UserGroupDC pDataContract) { pDataContract.UserGroupOid = pEntity.Oid; pDataContract.UserGroupVersion = pEntity.Version; pDataContract.Name = pEntity.Name; pDataContract.Description = pEntity.Description; pDataContract.Rights = new List(); var allrights = pEntity.Rights.Select(rr => rr.RightType).ToList(); foreach (var r in allrights) { var str = r.ToString(); long l = 0; if (!Int64.TryParse(str, out l)) { pDataContract.Rights.Add(r); } else { int test = 0; } //if () } return pDataContract; } private static List CreateSettingDcList(IList settingList) { var list = new List(); foreach (var item in settingList) { list.Add(new SettingsDC { SettingsOid = item.Oid, SettingsVersion = item.Version, Type = item.Type, Value = item.Value }); } return list; } private static List CreateUserGroupDcList(IList userGroups) { var list = new List(); foreach (var ug in userGroups) { var ugDc = new UserGroupDC(); ugDc.UserGroupOid = ug.Oid; ugDc.UserGroupVersion = ug.Version; ugDc.Name = ug.Name; ugDc.Description = ug.Description; ugDc.Rights = new List(); var allrights = ug.Rights.Select(rr => rr.RightType).ToList(); foreach (var r in allrights) { var str = r.ToString(); long l = 0; if (!Int64.TryParse(str, out l)) { ugDc.Rights.Add(r); } } list.Add(ugDc); } return list; } } }