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 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 && !(SessionFacade.LoggedInUser?.Oid is null)) { SessionFacade.LoggedInUser = 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) { return string.IsNullOrEmpty(context.Request.FilePath) || context.Request.FilePath.IndexOf("Admin.aspx") < 0; } 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 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.LoggedInUser = user; return true; } } return false; } 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.LoggedInUser = lUser; return true; } } return false; } 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()); } } } } }