Files
BeWoPlaner/Data/ASPHibernateSessionManager.cs
2024-10-30 16:12:10 +01:00

327 lines
11 KiB
C#

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)
{
userLoaded = TryAuthenticateWithGkv(context);
}
if(!userLoaded && !(SessionFacade.LoggedInUser?.Oid is null))
{
SessionFacade.LoggedInUser = DAOFactory.GenericDAO.LoadByID<ApplicationUser>(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.LoggedInUser = lUser;
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.LoggedInUser = user;
return true;
}
}
return false;
}
private static bool TryAuthenticateWithGkv(HttpApplication context)
{
if (context.Request.FilePath.IndexOf("GkvAbrechnungClient.aspx") == -1)
return false;
var appsettingip = System.Configuration.ConfigurationManager.AppSettings["App8IpAddress"];
var clientip = GetIP(true);
if (appsettingip != clientip)
return false;
var useroidstr = context.Request.Params["useroid"];
if (!long.TryParse(useroidstr, out long useroid))
return false;
SessionFacade.LoggedInUser = DAOFactory.GenericDAO.LoadByID<ApplicationUser>(useroid);
return true;
}
private static string GetIP(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<string, string> GetLoginInfoFromToken(string token)
{
if(string.IsNullOrWhiteSpace(token))
{
return new Dictionary<string, string>();
}
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<byte>();
int b;
do
{
b = csDecrypt.ReadByte();
if(b != -1)
{
bytes.Add(Convert.ToByte(b));
}
} while (b != -1);
return Encoding.UTF8.GetString(bytes.ToArray());
}
}
}
}
}