QxOrm and authentication

Forum for posting problems using QxOrm library

QxOrm and authentication

Postby nickla » Tue Jul 17, 2012 7:31 am

I didnt find answer for my question in this forum. How can i create authentication using QxOrm? I need to authenticate user.

I want to create method in my UserManager that will authenticate user, but i dont know how to send additional data (md5 hash of username and password) with each request. Can you help me?
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Re: QxOrm and authentication

Postby QxOrm admin » Tue Jul 17, 2012 12:04 pm

Hi,

I want to create method in my UserManager that will authenticate user, but i dont know how to send additional data (md5 hash of username and password) with each request. Can you help me?

QxOrm provides the class qx::QxSimpleCrypt to encrypt/decrypt some datas : http://www.qxorm.com/doxygen/html/class ... crypt.html
This class is used for example by QxService module (http://www.qxorm.com/doxygen/html/group ... rvice.html) to send encrypted datas over network.

To store an encrypted password in your database, you could imagine to have 2 properties in your class to manage the password :
1- one property containing the password returned by the GUI ;
2- another property (I think private) containing the encrypted password.
And in your table, you have only one column to manage associated to the second property (encrypted).

Then, using QxOrm triggers (http://www.qxorm.com/qxorm_en/faq.html#faq_130), you will be able to encrypt the password before saving an instance, or decrypt it after fetching.

For example, here is the file 'UserManager.h' :
Code: Select all
class QX_DLL2_EXPORT UserManager
{

   QX_REGISTER_FRIEND_CLASS(UserManager)

protected:

   long id;
   QString userName;
   QString userPassword;
   QString userPasswordEncrypted;

public:

   UserManager() : id(0) { ; }
   virtual ~UserManager() { ; }

   void onBeforeInsert(qx::dao::detail::IxDao_Helper * dao);
   void onBeforeUpdate(qx::dao::detail::IxDao_Helper * dao);
   void onBeforeDelete(qx::dao::detail::IxDao_Helper * dao);
   void onBeforeFetch(qx::dao::detail::IxDao_Helper * dao);
   void onAfterInsert(qx::dao::detail::IxDao_Helper * dao);
   void onAfterUpdate(qx::dao::detail::IxDao_Helper * dao);
   void onAfterDelete(qx::dao::detail::IxDao_Helper * dao);
   void onAfterFetch(qx::dao::detail::IxDao_Helper * dao);

};

QX_REGISTER_HPP_QX_DLL2(UserManager, qx::trait::no_base_class_defined, 0)

typedef boost::shared_ptr<UserManager> UserManager_ptr;

namespace qx {
namespace dao {
namespace detail {

template <>
struct QxDao_Trigger<UserManager>
{

   static inline void onBeforeInsert(UserManager * t, qx::dao::detail::IxDao_Helper * dao)   { if (t) { t->onBeforeInsert(dao); } }
   static inline void onBeforeUpdate(UserManager * t, qx::dao::detail::IxDao_Helper * dao)   { if (t) { t->onBeforeUpdate(dao); } }
   static inline void onBeforeDelete(UserManager * t, qx::dao::detail::IxDao_Helper * dao)   { if (t) { t->onBeforeDelete(dao); } }
   static inline void onBeforeFetch(UserManager * t, qx::dao::detail::IxDao_Helper * dao)    { if (t) { t->onBeforeFetch(dao); } }
   static inline void onAfterInsert(UserManager * t, qx::dao::detail::IxDao_Helper * dao)    { if (t) { t->onAfterInsert(dao); } }
   static inline void onAfterUpdate(UserManager * t, qx::dao::detail::IxDao_Helper * dao)    { if (t) { t->onAfterUpdate(dao); } }
   static inline void onAfterDelete(UserManager * t, qx::dao::detail::IxDao_Helper * dao)    { if (t) { t->onAfterDelete(dao); } }
   static inline void onAfterFetch(UserManager * t, qx::dao::detail::IxDao_Helper * dao)     { if (t) { t->onAfterFetch(dao); } }

};

} // namespace detail
} // namespace dao
} // namespace qx


And 'UserManager.cpp' file :
Code: Select all
QX_REGISTER_CPP_QX_DLL2(UserManager)

namespace qx {
template <> void register_class(QxClass<UserManager> & t)
{
   qx::IxDataMember * pData = NULL;

   pData = t.id(& UserManager::id, "id");
   pData = t.data(& UserManager::userName, "userName");
   pData = t.data(& UserManager::userPasswordEncrypted, "userPasswordEncrypted");

   pData = t.data(& UserManager::userPassword, "userPassword");
   pData->setDao(false); // Not a part of the table
}}

void UserManager::onBeforeInsert(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }

   // Encrypt password before saving
   QxSimpleCrypt crypto(QxConnect::getSingleton()->getEncryptKey());
   crypto.setCompressionMode(QxSimpleCrypt::CompressionNever);
   crypto.setIntegrityProtectionMode(QxSimpleCrypt::ProtectionChecksum);
   userPasswordEncrypted = crypto.encryptToString(userPassword);

   // Manage the error here !
   if ((crypto.lastError() != QxSimpleCrypt::ErrorNoError) || userPasswordEncrypted.isEmpty())
   { qAssert(false); return; }
}

void UserManager::onBeforeUpdate(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }

   // Encrypt password before saving
   QxSimpleCrypt crypto(QxConnect::getSingleton()->getEncryptKey());
   crypto.setCompressionMode(QxSimpleCrypt::CompressionNever);
   crypto.setIntegrityProtectionMode(QxSimpleCrypt::ProtectionChecksum);
   userPasswordEncrypted = crypto.encryptToString(userPassword);

   // Manage the error here !
   if ((crypto.lastError() != QxSimpleCrypt::ErrorNoError) || userPasswordEncrypted.isEmpty())
   { qAssert(false); return; }
}

void UserManager::onAfterFetch(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }

   // Decrypt password after fetching
   QxSimpleCrypt crypto(QxConnect::getSingleton()->getEncryptKey());
   userPassword = crypto.decryptToString(userPasswordEncrypted);

   // Manage the error here !
   if ((crypto.lastError() != QxSimpleCrypt::ErrorNoError) || userPassword.isEmpty())
   { qAssert(false); return; }
}

void UserManager::onBeforeDelete(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }
   // Nothing to do here !
}

void UserManager::onBeforeFetch(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }
   // Nothing to do here !
}

void UserManager::onAfterInsert(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }
   // Nothing to do here !
}

void UserManager::onAfterUpdate(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }
   // Nothing to do here !
}

void UserManager::onAfterDelete(qx::dao::detail::IxDao_Helper * dao)
{
   if (! dao) { qAssert(false); return; }
   if (dao->error().isValid()) { return; }
   // Nothing to do here !
}
QxOrm admin
 

Re: QxOrm and authentication

Postby nickla » Tue Jul 17, 2012 1:47 pm

Thank you.

Will this work on every SQL request?
How can i send user credentials from client ot server with each client request? This is needed to authenticate user in each request and to check his right.
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Re: QxOrm and authentication

Postby QxOrm admin » Tue Jul 17, 2012 3:17 pm

Will this work on every SQL request ?

Yes, if you use QxOrm triggers.

How can i send user credentials from client ot server with each client request ? This is needed to authenticate user in each request and to check his right.

If you are using QxService module (http://www.qxorm.com/qxorm_en/tutorial_2.html), each datas sent over network inherit from qx::service::IxParameter class (input and output, request and response).
So if you want to add your own informations on each requests (for example user credentials), you could imagine to create your own base class, like this :
Code: Select all
class MyBaseParameter : public qx::service::IxParameter
{
   // Add user credentials here
};


Then, instead of inherit from qx::service::IxParameter for each structures you send over network, you can inherit from MyBaseParameter ==> user credentials will be sent each time !
QxOrm admin
 

Re: QxOrm and authentication

Postby nickla » Tue Jul 17, 2012 5:07 pm

So simple. Thanks. I`ll try it.
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Re: QxOrm and authentication

Postby nickla » Tue Jul 17, 2012 5:12 pm

How can i authenticate user when qxService receives request? I want to authenticate user and check its access to service functions. How can i get method name in service constructor?

As i can see there is no ability to create trigger function before service function executes.
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Re: QxOrm and authentication

Postby QxOrm admin » Wed Jul 18, 2012 8:09 am

How can i authenticate user when qxService receives request? I want to authenticate user and check its access to service functions. How can i get method name in service constructor?
As i can see there is no ability to create trigger function before service function executes.

You have 2 events : transactionStarted() and transactionFinished() (search onTransactionFinished in the tutorial : http://www.qxorm.com/qxorm_en/tutorial_2.html).
Those events are called on each request.
But I'm not sure that it's possible to stop the process into transactionStarted() event (when authentification fails for example).

Another way is to create your own base class for services (a little bit like for parameters).
You have a virtual method named : virtual void registerClass() const ==> so you could override it to check your user for example and throw an exeption when authentification fails.
This way, for each request, you will be able to make your own checks...

Your own base class service could be something like this :
Code: Select all
template <class INPUT, class OUTPUT>
class MyBaseService : public qx::service::QxService<INPUT, OUTPUT>
{

public:

   MyBaseService(const QString & sServiceName) : qx::service::QxService<INPUT, OUTPUT>(sServiceName) { ; }
   virtual ~MyBaseService() { ; }

   virtual void registerClass() const
   {
      // Call base class registerClass() method
      qx::service::QxService<INPUT, OUTPUT>::registerClass();

      // Here are your own checks
      if (fails) { throw my_exception; }
   }

};

I think it should work... ;)
QxOrm admin
 

Re: QxOrm and authentication

Postby nickla » Wed Jul 18, 2012 8:58 am

QxOrm admin wrote:
Will this work on every SQL request ?

So if you want to add your own informations on each requests (for example user credentials), you could imagine to create your own base class, like this :
Code: Select all
class MyBaseParameter : public qx::service::IxParameter
{
   // Add user credentials here
};


Then, instead of inherit from qx::service::IxParameter for each structures you send over network, you can inherit from MyBaseParameter ==> user credentials will be sent each time !


In this case this is not working:
Code: Select all
class QX_SERVICE_DLL_EXPORT AbstractServiceInput : public qx::service::IxParameter
{
    QX_REGISTER_FRIEND_CLASS(AbstractServiceInput)
public:

protected:
    QString m_Username;
    QString m_Password;
};

// Following code will not execute in children
namespace qx {

    template <> void register_class(QxClass<AbstractServiceInput> & t)
    {
       t.data(& AbstractServiceInput::m_Username, "user");
       t.data(& AbstractServiceInput::m_Password, "passwd");
    }

    template <> void register_class(QxClass<AbstractServiceOutput> & t)
    {
       t.data(& AbstractServiceOutput::m_Username, "user");
       t.data(& AbstractServiceOutput::m_Password, "passwd");
    }

} // namespace qx

Code: Select all
// child example
class QX_SERVICE_DLL_EXPORT PhoneServiceInput : public AbstractServiceInput
{
    QX_REGISTER_FRIEND_CLASS(PhoneServiceInput);
public:
    PhoneServiceInput() : m_Id(0) { ; }
    virtual ~PhoneServiceInput() { ; }

    long id() const         { return m_Id; }
    PhonePtr phone() const  { return m_Phone; }

    void setId(const long value)        { m_Id = value; }
    void setPhone(const PhonePtr value) { m_Phone = value; }
protected:
    long m_Id;
    PhonePtr m_Phone;
};

// this is working...
namespace qx {

    template <> void register_class(QxClass<PhoneServiceInput> & t)
    {
       t.data(& PhoneServiceInput::m_Id, "id");
       t.data(& PhoneServiceInput::m_Phone, "phone");

       t.data(& PhoneServiceInput::m_Username, "user");
       t.data(& PhoneServiceInput::m_Password, "passwd");
    }

} // namespace qx


It would be nice if it will have ability to add user,password fields in parent class...

But... It is working and working good
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Re: QxOrm and authentication

Postby QxOrm admin » Wed Jul 18, 2012 9:29 am

It would be nice if it will have ability to add user,password fields in parent class...

You can register some properties in your base class, and don't have to register it in all your derived classes !
In your code, there is something missing, I think it is your problem (the second parameter is the base class) :
Code: Select all
QX_REGISTER_HPP_QX_SERVICE(PhoneServiceInput, AbstractServiceInput, 0)


Another note about your code : don't forget to call the base constructor when you write a derived class, something like this :
Code: Select all
PhoneServiceInput() : AbstractServiceInput(), m_Id(0) { ; }
QxOrm admin
 

Re: QxOrm and authentication

Postby nickla » Tue Aug 07, 2012 2:28 pm

This is not all that is needed. I solved this in such way:

abstractservice.h
Code: Select all
#ifndef ABSTRACTSERVICE_H
#define ABSTRACTSERVICE_H

#include "../../include/precompiled.h"

/* -- Service Input Parameters -- */

class QX_SERVICE_DLL_EXPORT AbstractServiceInput : public qx::service::IxParameter
{
    QX_REGISTER_FRIEND_CLASS(AbstractServiceInput)
public:

    void setUsername(const QString value)   { m_Username = value; }
    void setPassword(const QString value)   { m_Password = value; }

protected:
    QString m_Username;
    QString m_Password;
};
QX_REGISTER_HPP_QX_SERVICE(AbstractServiceInput, qx::service::IxParameter, 0)

/* -- Service Output Parameters -- */

class QX_SERVICE_DLL_EXPORT AbstractServiceOutput : public qx::service::IxParameter
{
    QX_REGISTER_FRIEND_CLASS(AbstractServiceOutput)
public:

    QString username() const    { return m_Username; }
    QString password() const    { return m_Password; }

protected:
    QString m_Username;
    QString m_Password;
};
QX_REGISTER_HPP_QX_SERVICE(AbstractServiceOutput, qx::service::IxParameter, 0)

#endif // ABSTRACTSERVICE_H


absractservice.cpp
Code: Select all
#include "../../include/precompiled.h"
#include "../../include/service/abstractservice.h"

#include <QxMemLeak.h>

QX_REGISTER_CPP_QX_SERVICE(AbstractServiceInput)
QX_REGISTER_CPP_QX_SERVICE(AbstractServiceOutput)

namespace qx {

    template <> void register_class(QxClass<AbstractServiceInput> & t)
    {
       t.data(& AbstractServiceInput::m_Username, "user");
       t.data(& AbstractServiceInput::m_Password, "passwd");
    }

    template <> void register_class(QxClass<AbstractServiceOutput> & t)
    {
       t.data(& AbstractServiceOutput::m_Username, "user");
       t.data(& AbstractServiceOutput::m_Password, "passwd");
    }

} // namespace qx
nickla
 
Posts: 52
Joined: Wed Jul 11, 2012 4:19 pm
Location: Russia

Next

Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 7 guests

cron