#1 2015-04-11 09:05:32

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

[TSQLRestServerAuthenticationHttpBasic] and others

Hi AB,

I was looking for a way to be able to manage access prohibited.

There is' a way to know on the server when a call is prohibited?

I would love to be able to have all the call to extract who is logging, that url was calling, his ip.

All this in order to realize two things: managing the attacks (ip ban with external firewall) may notify the user attempts wrong.

Tnx

Offline

#2 2015-04-12 07:01:32

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I've added TSQLRestServer.OnSessionFailed callback in addition to OnSessionCreate/OnSessionClosed.
It would be fired when authentication failed.
See http://synopse.info/fossil/info/1cc4677e59

Online

#3 2015-04-12 19:00:05

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Tnxs

Tomorrow I try

Offline

#4 2015-04-22 21:26:28

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

there is something wrong...

      // 2. handle security
      if (not Ctxt.Authenticate) or
         ((Ctxt.Service<>nil) and
           not (reService in Call.RestAccessRights^.AllowRemoteExecute)) then
        Ctxt.AuthenticationFailed else

Ctxt.AuthenticationFailed never fire.

I suspect that the function ctxt.authenticate returns true when it should return false.

I have no patch available now

Offline

#5 2015-04-22 21:44:58

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I rewrote the function, as I think should be its logic


function TSQLRestServerURIContext.Authenticate: boolean;
var aSession: TAuthSession;
    i: integer;
begin
  if Server.HandleAuthentication then
  begin
   result := false;
   Session := CONST_AUTHENTICATION_SESSION_NOT_STARTED;
   Server.fSessions.Lock;
   try
    aSession := nil;
    if Server.fSessionAuthentication<>nil then
    begin
     for i := 0 to length(Server.fSessionAuthentication)-1 do
     begin
      aSession := Server.fSessionAuthentication[i].RetrieveSession(self);
      if aSession<>nil then
      begin
       {$ifdef WITHLOG}
       log.Log(sllUserAuth,'%/%',[aSession.User.LogonName,aSession.ID],self);
       {$endif}
       SetString(fSessionAccessRights,PAnsiChar(@aSession.fAccessRights),
       sizeof(TSQLAccessRights)); // override access rights
       Call^.RestAccessRights := pointer(fSessionAccessRights);

       result:=true;
       exit;
      end;
     end;
    end;
   finally
    Server.fSessions.UnLock;
   end;
   if ((Service<>nil) and Service.ByPassAuthentication) or
      ((MethodIndex>=0) and Server.fPublishedMethod[MethodIndex].ByPassAuthentication) then
   begin
    result:=true;
    exit;
   end;
  end
  else
  begin// default unique session if authentication is not enabled
    Session := CONST_AUTHENTICATION_NOT_USED;
    result := true;
  end;
end;


with my test program **NOT** works, but you have to see if it does what it needs

Last edited by Sabbiolina (2015-04-22 22:01:22)

Offline

#6 2015-04-23 07:46:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Please try http://synopse.info/fossil/info/e8335540d3

I refactored TSQLRestServerURIContext.Authenticate so that it should handle the authentication as expected.

Thanks for your feedback!

Online

#7 2015-04-24 14:26:01

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

unfortunately it does not work.

I write a little cli/srv program, so you can debug.

ServerHB.pas

program ServerHB;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  SynCommons, SynLog, mORMot,MormotHTTPserver,
  mORMotSQLite3, SynSQLite3Static;

const
 SERVER_PORT='888';

type
  ICalculator = interface(IInvokable)
    ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
    function Add(n1,n2: integer): integer;
  end;

  Tmysess = class
   function myerror(Sender: TSQLRestServer; Session: TAuthSession; Ctxt: TSQLRestServerURIContext): boolean;
  end;

  TMYAuthUser = class(TSQLAuthUser)
  private
   Fenabled:boolean;
  published
   property enabled: Boolean read Fenabled write Fenabled; // abilitato o no

   function CanUserLog(Ctxt: TSQLRestServerURIContext): boolean; override;
  end;

  TServiceCalculator = class(TInterfacedObject, ICalculator)
  public
    function Add(n1,n2: integer): integer;
  end;

function TServiceCalculator.Add(n1, n2: integer): integer;
begin
  result := n1+n2;
end;

function TMYAuthUser.CanUserLog(Ctxt: TSQLRestServerURIContext): boolean;
begin
 result:=true;
end;

function Tmysess.myerror(Sender: TSQLRestServer; Session: TAuthSession; Ctxt: TSQLRestServerURIContext): boolean;
var
 tmp:rawutf8;
begin
 tmp:=ctxt.Call.InHead;
 writeln('fail_inhead:'+tmp);
 tmp:=ctxt.InHeader['Authorization'];
 writeln('fail_auth:'+tmp);
 result:=false;
end;

var
  aModel: TSQLModel;
  Restsrv:TSQLRestServerDB;
  u:TMYAuthUser;
  aHttpServer:TSQLHttpServer;
  mySess:Tmysess;
begin
  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
    EchoToConsole := LOG_VERBOSE; // log all events to the console
  end;
  TInterfaceFactory.RegisterInterfaces([TypeInfo(ICalculator)]);
  mysess:=Tmysess.Create;
  aModel := TSQLModel.Create([TMYAuthUser,TSQLauthGroup]);
  try
    Restsrv:=TSQLRestServerDB.Create(aModel,':memory:',false);
    try
      restsrv.CreateMissingTables; // we need AuthGroup and AuthUser tables
      restsrv.AuthenticationRegister(TSQLRestServerAuthenticationHttpBasic);

      u:=TMYAuthUser.Create;
      u.LogonName:='myuser';
      u.DisplayName:='Test User';
      u.PasswordPlain:='test';
      u.enabled:=true;
      u.GroupRights:=TSQLAuthGroup(3);
      RestSrv.Add(U,true);
      u.Free;
      if not RestSrv.TableHasRows(TSQLAuthGroup) then
       TSQLAuthGroup.InitializeTable(RestSrv,'',[itoNoIndex4ID, itoNoIndex4UniqueField, itoNoIndex4NestedRecord, itoNoIndex4RecordReference]);

      restsrv.ServiceDefine(TServiceCalculator,[ICalculator],sicpersession);
      RestSrv.OnSessionFailed:=mysess.myerror;
      aHttpServer:=TSQLHttpServer.Create(SERVER_PORT,[RestSrv],'+',useHttpApiRegisteringURI);
      aHttpServer.AccessControlAllowOrigin:='*'; // allow cross-site AJAX queries

      write('Press [Enter] to close the server.');
      readln;
    finally
      restsrv.Free;
    end;
  finally
    aModel.Free;
  end;
end.

ClientHB.pas

program ClientHB;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  SynCommons, SynLog, mORMot,MormotHTTPserver,
  mORMotSQLite3, SynSQLite3Static,mORMotHttpClient;

const
 CLIENT_PORT='888';
 CLIENT_ADDR='localhost';

type
  ICalculator = interface(IInvokable)
    ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
    function Add(n1,n2: integer): integer;
  end;


var
 aModel:TSQLModel;
 aClient:TSQLHttpClient;
 I:ICalculator;
begin
  with TSQLLog.Family do begin
    Level := LOG_VERBOSE;
//    EchoToConsole := LOG_VERBOSE; // log all events to the console
  end;
   TInterfaceFactory.RegisterInterfaces([TypeInfo(ICalculator)]);
 aModel := TSQLModel.Create([TSQLAuthUser]);
 aClient := TSQLHttpClientWinHTTP.Create(CLIENT_ADDR,CLIENT_PORT,aModel);

 writeln('auth WRONG test:');
 if TSQLRestServerAuthenticationHttpBasic.ClientSetUser(aClient,'myuser','test2',passClear) then
 begin
  writeln('auth OK');
  aClient.ServiceDefine([ICalculator],sicpersession);
  if aClient.Services['Calculator'].Get(I) then
   writeln('result: '+ intToStr(I.Add(2,3)));
 end
 else Writeln('auth KO');
 writeln('');
 writeln('auth RIGHT test:');
 if TSQLRestServerAuthenticationHttpBasic.ClientSetUser(aClient,'myuser','test',passClear) then
 begin
  writeln('auth OK');
  aClient.ServiceDefine([ICalculator],sicpersession);
  if aClient.Services['Calculator'].Get(I) then
   writeln('result: '+ intToStr(I.Add(2,3)));
 end
 else Writeln('auth KO');

 write('Press [Enter] to close the client.');
 readln;
end.

Offline

#8 2015-04-25 08:45:23

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Thanks to your programs, I found out what was not as you expected.

I've ensured that TSQLRestServer.OnSessionFailed event is called when the incoming credential (e.g. username or password) are incorrect.
Previous implementation only triggered the event when the URI signature was invalid.

Warning: any overriden TSQLRestServerURIContext.AuthenticationFailed method should call the inherited method to ensure OnSessionFailed is called.

See http://synopse.info/fossil/info/731aeccc46

Online

#9 2015-04-26 06:54:19

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

we are almost there ...

but, for the http basic need a small patch

function TSQLRestServerAuthenticationHttpBasic.Auth(Ctxt: TSQLRestServerURIContext): boolean;
var userPass,user,pass,expectedPass: RawUTF8;
    U: TSQLAuthUser;
    Session: TAuthSession;
begin
  if Ctxt.InputExists['UserName'] then begin
    result := false; // allow other schemes to check this request
    exit;
  end;
  result := true; // this authentication method is exclusive to any other
  if GetUserPassFromInHead(Ctxt,userPass,user,pass) then begin
    U := GetUser(Ctxt,user);
    if U<>nil then begin
    try
      expectedPass := U.PasswordHashHexa;
      U.PasswordPlain := pass; // override with SHA-256 hash from HTTP header
      if U.PasswordHashHexa=expectedPass then begin
        fServer.SessionCreate(U,Ctxt,Session);
        if Session<>nil then begin
          // see TSQLRestServerAuthenticationHttpAbstract.ClientSessionSign()
          Ctxt.SetOutSetCookie((COOKIE_SESSION+'=')+CardinalToHex(Session.IDCardinal));
          Ctxt.Returns(['result',Session.IDCardinal,'logonname',Session.User.LogonName]);
          exit; // success
        end;
      end;
    finally U.Free; end
   end;
   Ctxt.AuthenticationFailed; //<---------------------------  moved
   exit;
  end;
  Ctxt.Call.OutHead := 'WWW-Authenticate: Basic realm="mORMot Server"';;
  Ctxt.Error('',HTML_UNAUTHORIZED); // will popup for credentials in browser
end;

I moved the call Ctxt.AuthenticationFailed,
because in the case of existing user with the wrong password, the sesionfail was not called

Offline

#10 2015-04-26 07:06:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Please check http://synopse.info/fossil/info/a067d1529e

Thanks for the feedback.

Online

#11 2015-04-27 08:37:26

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Another update.
We have introduced a breaking change, to add some feature to the authentication failure callback.

We renamed the TSQLRestServer.OnSessionFailed event as TSQLRestServer.OnAuthenticationFailed, including a new TNotifyAuthenticationFailedReason parameter so that the callback would be able to identify which kind of failure did occur.
See http://synopse.info/fossil/info/59a04453f1

Online

#12 2015-04-27 10:35:52

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I received this email from you:

Fjodr wrote:

lease check the changes Sabbiolina and I have been making to mORMot.pas

We have added an event handler to create a callback to use our own password verification scheme.

At the moment we ONLY modified the HTTP BASIC authentication class, but if you like our solution I’m sure you can easily “incorporate and port” it to all other auth types.

I think that freeing users from having to stick to the built-in auth scheme and classes would be a great plus for mORMot!

Good ideas.

About the password check, you can already override and TSQLRestServerAuthentication class, and provide your own customized password validation, or - even better perhaps, for your particular case - create you own TSQLAuthUser class and change how password is stored.
This is IMHO a better approach that shared events, which are highly depending on the authentication class itself (e.g. it does not make sense to have such an event in SSPI authentication mode).

About the user retrieval, you can already override the TSQLRestServerAuthentication.GetUser virtual method.
But perhaps it is not enough, since getting the user is common to all TSQLRestServerAuthentication classes.
So I've introduced the TSQLRestServer.OnAuthenticationUserRetrieve optional event, which would be used by TSQLRestServerAuthentication.GetUser to retrieve the TSQLAuthUser instance from a given name.
See http://synopse.info/fossil/info/9c496920bb

Thanks for the feedback.

Online

#13 2015-04-27 16:19:57

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Hello! smile
Thank you... but... deriving from your base (user) class would be possible if it was a new software, where you don't have to deal with legacy classes.
Not to mention that deriving would still require the modification of mORMot.pas, given the amount of protected members you use.
But when you are integrating mORMot into an existing 8-year-old code, you need enough flexibility to use your old classes (TMyUserProfile) as changing them would require way too much work to justify the effort.
So the changes that Sabbiolina and I made were thought/designed to give mORMot this kind of flexibility.
Wouldn't you agree?

Offline

#14 2015-04-27 17:22:33

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

IMHO in your case, a dedicated TSQLRestServerAuthentication class is the preferred and cleaned way of implementing it.

Online

#15 2015-04-27 19:22:32

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Everything can be improved
I think it's the spirit of open source.

Leaving aside the usefulness or not to rewrite a new class of authentication httpbasic, I think the CheckCredential, as has been thought, is more efficient function that I have proposed and implemented long ago: CanUserLog.

The checkCredential, without changing a single line of mormot.pas, allows a developer to have full control, if he likes it, the authentication process could easily integrate with any variables derived from object tsqlauthuser.

While canUserLog, acting perhaps a little late in the authentication process, removing the ability to implement custom rules.

Offline

#16 2015-04-28 19:52:30

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Indeed.

But I would not add a global TSQLRestServer.OnCheckPassword event, since it would not make sense for any supported authentication scheme, but when the password is transmitted as plain information.

I've therefore enhanced HTTP Basic authentication (which transmit the password from client to server side), to allow any kind of customization:
  *  added TSQLRestServerAuthenticationHttpBasic.CheckPassword() virtual method, so that you may customize the password check by overriding it
  *  defined GetUserPassFromInHead method as virtual, so that you could implement you own password transmission pattern, if the default awfully weak "Authorization: Basic ...." header does not fit your expectations

See http://synopse.info/fossil/info/835ea10b2f

Hope it helps.
Thanks for your feedback.

Online

#17 2015-04-28 21:03:18

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Tomorrow I'll try to improve the function checkpassword to meet the needs of existing authentication systems.

The endeavor to create a new class that inherits from authattpbasic just for that single detail (which by the way would be useful to everybody and would not break compliance with the HTTP Basic Auth standard) just seems to me like an unjustified waste of time...

Offline

#18 2015-04-28 22:40:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

A few more lines of code, perhaps.

But a much better design, and the opportunity to avoid potential misuses.
A global event would clearly break the liskov substitution principle I'm afraid...

Online

#19 2015-04-28 23:19:48

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

What's the matter?
have a simple checkpassword violates the principles?

canUserLog instead?

Offline

#20 2015-04-29 06:16:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I gave the reason just above:

I would not add a global TSQLRestServer.OnCheckPassword event, since it would not make sense for any supported authentication scheme, but when the password is transmitted as plain information.

A global event, at TSQLRestServer level, should have the same effect, whatever the TSQLRestServerAuthentication class is.
This is tied to the Liskov principle: a behavior should be explicit, whatever actual implementation is.

For TSQLAuthUser.CanUserLog, this event will be used whatever the TSQLRestServerAuthentication class is.
Whereas  a TSQLAuthUser.CheckPassword, with a plain password, would only be called for TSQLRestServerAuthenticationHttpBasic. This would be a cause of confusion, for sure.

Online

#21 2015-04-29 09:51:46

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I looked at the use of passwords in mormot.pas

As you say, it is difficult to unify control of password authentication for all systems.

Especially for the use of passwordhexA as SALT communication.
Let me say that your constant 'salt' used between client and server is cryptographically poor, and hides a big problem in my opinion:

if you had a real cryptographic salt for each user how to connect a client to the server?
the client should already know the SALT.


Indeed passwordhexA = sha256 ('salt' + password);

perhaps think of a signature property in user with a separate management of the password might be interesting.

Offline

#22 2015-04-29 10:57:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I'm afraid you are missing some points of the authentication process.

A fixed salt is not cryptographically poor, for the authentication scheme itself.
Its purpose is to avoid brute force resolution of the hashed password, if the server side database has been hacked.
In fact, the safety comes from the strong cryptography of SHA-256 itself.
Some standard does not even use a fixed salt.

The idea is that the dual-phase challenge is where the safety comes from.
In the dual-phase challenge, the salt changes at each request.
So it is even much more stronger than another per-user or per-application salt, as you propose.

This is why the BASIC authentication is weak, and should never be used.
As soon as you use TSQLRestServerAuthenticationHttpBasic, your authentication is weak.
Changing the way it is stored on the server would not help.

Online

#23 2015-04-29 16:52:49

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Pardon me for the intrusion, I used to teach Operating Systems Security at the University back in my country of origin, and I agree with Sabbiolina on the fact that a fixed salt is a pretty weak solution.
In fact your authentication scheme is so peculiar that it's pretty easy to "guesstimate" the REST service was built with mORMot, and your library is open source, therefore it would take seconds to an attacker to download your source code and realize the salt is constant. Using such information it would be fairly easy to bruteforce the back-end DB directly.
On top of that: a constant salt and no salt at all is basically the same thing from a cryptoanalytical strandpoint, as 2 salted SHA256's of the same password will result in the exact same has code:
- SHA256 of "saltMyPassword" is identical to SHA256 of "saltMyPassword", whereas
- SHA256 of "1234MyPassword" is not the same as SHA256 of "5678MyPassword"
In the latter case, in fact, because of the 2 different salts, the hash codes of the same password would be different, de facto preventing most linear and differential crypto-analysis attacks.

Offline

#24 2015-04-29 16:57:35

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: [TSQLRestServerAuthenticationHttpBasic] and others

Changing the way it is stored on the server would not help.

Again, since your library is a framework, it is not good to assume all your users are developing NEW software (and thus have the ability to structure the back-end DB as you suggest).
When you have to integrate new parts in a very large existing software, sometimes you have to "make do".
So, let's say that we're dealing with an existing DB, where salts and password-hashes are already stored that way, in separate fields... I do believe Sabbiolina's solution here would make your library flexible enough to handle such case with a minimal amount of lines of code (as opposed to reinventing the wheel, and subclassing a class that can only be subclassed inside mORMot.pas due to the large use of protected members). Wouldn't you agree?

Last edited by BBackSoon (2015-04-29 16:58:35)

Offline

#25 2015-04-29 18:42:13

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

@BBackSoon
This was exactly what I stated: a fixed salt is weak, but if you store a variable salt within the User record, or use a custom application-dedicated salt, it would not make a big difference.

I disagree a little about the fact that "a constant salt and no salt at all is basically the same thing".
From a real attacker point of view a salt, even fixed, is better than no salt, since you can't use brute-force pre-computed dictionnary.
With a custom salt, you need to compute all SHA, whereas with no salt, you can use pre-existing pre-computed dictionary, which are in every attacker tool box.

And you can store the TSQLAuthUser+TSQLAuthGroup tables in a crypted SQlite3 database, difficult to decrypt without the private key...
If the attacker is able to access the back-end DB, I would not fear about breaking the password in brute force.
There will be much worse to be done if you access the back-end computer!

Once again, the main point of the "default" mORMot security scheme is the dual-phase challenge at the initialization phase, then signature of every request, at URI level, with a time-based nonce.
This is were the security relies.
The password, nor its hash with a fixed salt, is never transmitted on the wire.
The password storage is IMHO strong enough, and you have the ability to change how it is stored easily by sub-classing the TSQLAuthUser if needed.

Sabbiolina is using basic authentication, with the password transmitted in clear!
A custom password check on the server is just a no benefit, when using such a weak authentication.

I do not see what is wrong with subclass a mORMot class.
You can inject any external existing code in the subclass.
There is in fact no new DB needed: you can create a TSQLAuthUser on the fly from an existing DB, and it would work.

Whereas putting a shared event on the main TSQLRestServer would IMHO just introduce confusion, since we support several authentication schemes.
Such an event would imply that the password is send as plain from the client side, which is the worse and weaker design we could imagine.
This is why I did not want to go into this direction.

Online

#26 2015-04-29 20:28:35

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: [TSQLRestServerAuthenticationHttpBasic] and others

I know that the HTTP Basic authentication is inherently weak, in fact Sabbiolina is forcing it through a TLS channel. Yet it still remains fairly weak for other reasons.

But it's compatible. If mORMot had supported a more secure - yet highly compatible - authentication scheme, like OAuth(2) for instance, we would have gone that way.

mORMot's native auth scheme, with its two-phase challenge, is strong, but it's a pain if you need to create an API to be accessed by apps written in PHP, Python, Ruby, Java, C# (etc...) because no one wants to implement the client-side of mORMot's auth scheme when the languages they use already have very reliable and mature OAuth client libraries they could leverage upon.

On top of that consider when you have zero control over the backend DB, and you have to abide to restrictions (no SQLite for example) imposed by either the software or the politics behind it... then you need a framework flexible enough to let you go around these hurdles.

Summarizing: OAuth(2) is really a must if we don't want to pretend that every developer in the world uses Delphi/mORMot... in the meantime - waiting for OAuth(2) - a HTTP Basic Auth inside a TLS channel with some more flexibility would be good enough (temporarily).

Offline

#27 2015-04-29 21:41:15

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: [TSQLRestServerAuthenticationHttpBasic] and others

About HTTP Basic auth, even over TLS it is weak, since it is subject to MIM attacks if certificates are not fully trusted...

Yes OAuth2 is a need, since it is standard.
But its implementations could be found  very weak - weaker than the mORMot default authentication, in all means.
For instance, reading of http://tools.ietf.org/html/rfc6749 is informative:
- The password is sent as plain text, e.g. via HTTP basic authentication;
- The Access Token is sent as HTTP header, regardless of the resource accessed, and with cross-origin abilities;
- Due to all those weaknesses, TLS is needed... even if it is no silver bullet either.
One of the initial authors quit the group and withdrew its name from the RFC... see http://hueniverse.com/2012/07/26/oauth- … d-to-hell/

OAuth2 is pretty sensitive to MIM and Replay attacks, and has a lot of well identified threats.
This is well documented - see https://tools.ietf.org/html/rfc6819

There is a pending port for mORMot - see http://synopse.info/forum/viewtopic.php … 780#p15780
Any help introducing it in the framework is welcome.

The scheme used by mORMot, with a dual-step challenge and a nonce-based URI/resource level signature, is somewhat stronger.
You may consider even using mORMot without HTTPS.


I do not understand what is wrong with Sqlite, which is the most widely deployed database, and probably the most tested and safest db in the world.
But even SQlite3 is not mandatory in mORMot.
As I wrote, you can store the users in any kind of storage, just create the TSQLAuthUser instance on the fly.

We have Java and JavaScript clients available.
Others submissions, using mustache templates are welcome.

Online

Board footer

Powered by FluxBB