I have JWT tokens working well now with custom User Session working nicely.
For us now, we want to Authorize the method call according to the AccountId contained in the request objects. e.g. If you are requesting objects for company A (request), you yourself must be from company A.(session)
Currently I am doing this as follows:
public object Any(GetObjects request)
{
if (Authorize(request)){
using (var db = DbFactory.Open())
{
CheckTableExistsAndInitialize<Object>(db);
var response = db.LoadSelect<Object>()
.Where(x => x.AccountID == request.AccountID);
return response.ToList<Object>();
}
}
else
{
return null;
}
}
With the Authorize call using reflection in a service class, to check jwt session accountid against request accountid as:
public bool Authorize(Object msg)
{
try
{
var session = (GetSession() as CustomSession);
bool validAccount = false;
// If Request contains AccountId then Return Authorized if AccountId matches Request Object.
if ((msg != null) && (msg.GetType().GetProperty("AccountID") != null))
{
if (session != null)
{
var guid = new Guid(session.AccountID);
var account = (Guid)msg.GetType().GetProperty("AccountID")?.GetValue(msg);
validAccount = (guid == account);
}
}
// Return True if Role is SysAdmin.
if (validAccount || session.Roles.Contains("SysAdmin"))
{
return true;
}
}
catch (Exception ex)
{
}
What I really want however is to do it like:
[Authenticate HasRole("SysAdmin") || HasAccount(request)]
public object Any(GetObjects request)
{
using (var db = DbFactory.Open())
{
CheckTableExistsAndInitialize<Object>(db);
var response = db.LoadSelect<Object>()
.Where(x => x.AccountID == request.AccountID);
return response.ToList<Object>();
}
}
}
The above obviously does not work yet as the request is not in scope yet,
Is there a way I can achieve this in this way or at a higher message handler level ?