Showing classes, but cannot get a list of a class

Hi!

I have a strange situation. XData and Aurelius.

First a login is needen to get the JWT (and is used later in requests).

If I use this URL:

http://192.168.10.200:9001/internal

I get the list of classes

{
"value": [
{
"name": "TitaniaApp",
"url": "TitaniaApp"
},
{
"name": "EnvironmentApp",
"url": "EnvironmentApp"
},
{
"name": "Environment",
"url": "Environment"
},
{
"name": "Customer",
"url": "Customer"
},
{
"name": "Server",
"url": "Server"
},
{
"name": "EnvironmentUser",
"url": "EnvironmentUser"
}
]
}

But if I do a list of a single class,

http://192.168.10.200:9001/internal/server

then I get an error HTTP ERROR 403

I tried to do the same in Postman and get the same error. Please note that the login is done and JWT used for listing.

The TServer class is defined like this:

  [Entity]
  [EntityAuthorize]
  [Model('Admin')]
  [Table('server')]
  [Id('FAddress', TIdGenerator.None)]
  TServer = class
  ...
  end;

XDataServer component is configured this way:

  object XDataServer: TXDataServer
    BaseUrl = 'http://+:9001/internal'
    Dispatcher = SparkleHttpSysDispatcher
    Pool = XDataConnectionPool
    ModelName = 'Admin'
    RoutingPrecedence = Service
    DefaultEntitySetPermissions = [List, Get, Insert, Modify, Delete]
    EntitySetPermissions = <>
    SwaggerOptions.Enabled = True
    SwaggerUIOptions.Enabled = True
    SwaggerUIOptions.ShowFilter = True
    Left = 72
    Top = 80
    object XDataServerCompress: TSparkleCompressMiddleware
    end
    object XDataServerJWT: TSparkleJwtMiddleware
      Secret = '*****'
    end
  end

My guess is that client is not authenticating (JWT is not being sent). Try, for example, set ForbidAnonymousAccess property of JWT middleware to True.

If the client is not authenticating, this would cause even the http://192.168.10.200:9001/internal address to return 403. Can you please check that?

Hi!

Client code is set to send the JWT, but if I set a breakpoint in the line Req.Headers.SetValue.. it's never hit.

I checked - the variable JwtToken is correctly filled with data.

  Client := TXDataClient.Create;
  Client.Uri := AppSettings.ClientUri;
  JwtToken := Client.Service<ILoginService>.Login(AppSettings.ClientUser , AppSettings.ClientPass);

  Client.HttpClient.OnSendingRequest := procedure(Req: THttpRequest)
    begin
      Req.Headers.SetValue('Authorization', 'Bearer '+JwtToken);
    end;

  list := Client.List<TServer>;  <-- Error here

.. i something wrong with the client code..?

If I set ForbidAnonymousAccess to false, I get 401 when calling ILoginService.Login.

You were right, was an authentication problem. The server part is now working correctly, I can login and access CRUD services in Postman.

Case closed, Sherlock! :)

1 Like

Maybe I' ve been too quick :( I still have a problem in the client (CRUD and service operations are working correctly in Postman). I get this error:

Interface "ILoginService" not registered as a service contract.

when calling

JwtToken := Client.Service<ILoginService>.Login(AppSettings.ClientUser, AppSettings.ClientPass);

I checked the parameters and are OK. In Postman the call is executed correctly, so I assume the server is working fine.

unit LoginServiceInterface;

interface

uses
  System.Classes,
  Generics.Collections,
  XData.Service.Common,
  Aurelius.Criteria.Base,
  XData.Security.Attributes,
  Aurelius.Mapping.Attributes,
  Admin.Entities;

type
  [ServiceContract]
  [Model('Admin')]
  ILoginService = interface(IInvokable)
    ['{3B1C0691-6D7C-41FF-9F47-BD6392C2CC9F}']
    [HttpPost]
    function Login(const User, Pass: string): string;
  end;

implementation

initialization
  RegisterServiceType(TypeInfo(ILoginService));

end.

The interface is the same file for the server and client. I'm quite sure the problem is in the client, but can't understand where.

Your ILoginService interface is mapped to model Admin only, so it will only work if your client is created to work with that model:

Client := TXDataClient.Create(TXDataAureliusModel.Get('Admin'));

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.