#1 2024-10-08 16:45:44

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

How to use Authentication by user/password?

I would like to implement user/password authentication. What is the simplest way to achieve this (perhaps using TRestServerAuthenticationDefault)?

Additionally, how can I implement and verify it on the server side without using ORM part?

I mean, I need to check if user/password are Ok and, at the same time, use the username (after it was validate) on server side.

Last edited by mdbs99 (2024-10-08 17:13:35)

Offline

#2 2024-10-09 07:07:01

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

Re: How to use Authentication by user/password?

Hello,
If you don't want to mess with ORM/REST auth, the easiest is to implement it at HTTP Server level.
You can enable digest authentication for instance.

Offline

#3 2024-10-09 08:59:56

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

Could you give me an example of how to do this?

My ideas are:
- the service will get the data of all users when it is started — I will get it "manually", with a query and saving it in some object for each thread instantiated
- the client will log in, using a method of the service, to start the application
- then, for each method called (interface-based) the server should read the username sent in the requests "somewhere that I don't know how yet" — because I don't want to have to send the username as a parameter of each method of the interface

PS: I'm using Delphi 7.

Last edited by mdbs99 (2024-10-09 09:05:20)

Offline

#4 2024-10-09 10:37:20

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

The client side have Client.SetUser(user, passwd) method (TRestHttpClient class).

On the server side, how can I obtain this same information (user, passwd), within the implementation of the class that implements the interface (which is shared between client and server, i.e., interface-based)?

Offline

#5 2024-10-09 11:20:56

tbo
Member
Registered: 2015-04-20
Posts: 353

Re: How to use Authentication by user/password?

Perhaps this example will help you. Take a closer look at function TCustomServiceObject.GetSessionUserDirName.

With best regards
Thomas

Offline

#6 2024-10-09 15:58:43

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

Thanks Thomas,

But I couldn't see any call to `Server.AuthenticationRegister(TRestServerAuthenticationDefault)` or so in this example.

If I don't use this line, in my code, there is no authentication and no error — but I need authentication...

I can't compile this example, as it uses another (newer) Delphi version — I'm using D7.

Offline

#7 2024-10-09 16:09:26

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

On the client side I'm using

Client.SetUser(User.UserName, User.Password)

.

Then, I've adapted the example code as this:

var
  vAuthUser: TAuthUser;
begin
  vAuthUser := TAuthUser(Server.SessionGetUser(ServiceRunningContext.Request.Session));
  if Assigned(vAuthUser) then
  try
    // => vAuthUser is always NIL...
  finally
    vAuthUser.Free;
  end;

  // my own code here...

end;

But `vAuthUser` is always NIL.

And if I set

Server.AuthenticationRegister(TRestServerAuthenticationDefault)

, the authentication fails directly, without even enter on the method.

I don't want to use "model", but for testing I added

CreateWithOwnModel([TAuthGroup, TAuthUser], {HandleUserAuthentication=} True);

like the example, but then I got errors:

20241009 16175800 EXC   EModelException {Message:"TAuthUser is not part of TOrmModel root=root"} [Main] at 443f23
20241009 16175800  +    serv.core.TTaskServer(02472660).Shutdown() root CurrentRequestCount=0
20241009 16175800  -    00.000.837
20241009 16175800 info  serv.core.TTaskServer(02472660) TRest.Destroy root
20241009 16180217 EXC   EModelException {Message:"TAuthUser is not part of TOrmModel root=root"} [Main] at 443f23
Exception EModelException in module serv.exe at 00043F23.
TAuthUser is not part of TOrmModel root=root.

This part is VERY confusing and I couldn't find any place that explains this — even in ChatGPT.

Can you help me?

Last edited by mdbs99 (2024-10-09 16:22:22)

Offline

#8 2024-10-09 16:49:11

tbo
Member
Registered: 2015-04-20
Posts: 353

Re: How to use Authentication by user/password?

mdbs99 wrote:

I don't want to use "model", but for testing I added

CreateWithOwnModel([TAuthGroup, TAuthUser], {HandleUserAuthentication=} True);

like the example, but then I got errors:

You have to write:

CreateWithOwnModel([TAuthGroup, TFileAuthUser], {HandleUserAuthentication=} True, ROOT_NAME_FILE);

Compatibility with Delphi 7 should be possible. Remove the inline variables. You can rewrite the function u_ServiceUtils.CheckFileName with mORMot's own functions to get rid of TPath. You can replace TWebBrowser component with a TMemo. Then only text files are possible.

With best regards
Thomas

Last edited by tbo (2024-10-09 16:50:14)

Offline

#9 2024-10-09 17:11:37

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

Instead of using ROOT_NAME_FILE, I simply wrote 'root'.

Since I don't have TFileAuthUser, I replaced it with TAuthUser in my code. However, this led to the errors I mentioned earlier, which is quite confusing.

Without this example, how would a user even know how to implement this correctly? I still don't know how to do it  sad

By the way, my mORMot2 version is up to date as of yesterday.

Offline

#10 2024-10-10 09:13:32

flydev
Member
From: France
Registered: 2020-11-27
Posts: 73
Website

Re: How to use Authentication by user/password?

I couldn't see any call to `Server.AuthenticationRegister(TRestServerAuthenticationDefault)` or so in this example.

as scheme name let suggest, it's implemented by default when using `true` for HandleUserAuthentication on Create*(), see lines mormot.rest.server.pas#L6176-L6181


EXC   EModelException {Message:"TAuthUser is not part of TOrmModel root=root"} [Main] at 443f23

TFileAuthUser is just derived from TAuthUser. Pheraps try with a more basic sample and then go further, I just published a project based on @martindoyle sample (04) and using a part of @tbo example,  you should be able to compile it on D7, grab it from flydev-fr/sample_interfacebasedservice

Hope it help.

Offline

#11 2024-10-10 20:36:40

tbo
Member
Registered: 2015-04-20
Posts: 353

Re: How to use Authentication by user/password?

I have made the source code for the article example compilable with Delphi7. It can be downloaded from this post.

With best regards
Thomas

Offline

#12 2024-10-11 11:36:25

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How to use Authentication by user/password?

@flydev @tbo

Sorry for the delay — I had other issues here.

I will study both examples and write feedback to you as soon as possible.

Thank you both for your time.

Offline

Board footer

Powered by FluxBB