We are using XDATA for REST SERVER and trying user LoginService according demo. We have the token with success full but when user POSTMAN for other functions ("Example: Table Acesso") receive message "User not Authorized". Code Delphi Server:
unction TaccesoService.Getacceso_id(codigo: Integer): Tacceso;
var
User: IUserIdentity;
begin
User := TXDataOperationContext.Current.Request.User;
if User = nil then
raise EXDataHttpUnauthorized.Create('User not authenticated');
if not (User.Claims.Exists('admin') and User.Claims['admin'].AsBoolean) then
raise EXDataHttpForbidden.Create('Not enough privileges');
Query.SQL.Text := 'SELECT * FROM ACESSO WHERE CODIGO = :codigo';
Query.ParamByName('codigo').AsInteger := codigo;
Query.Open;
if Query.IsEmpty then Exit(nil);
Dear Wagner. Thaks for your reply. Below the 3 units related with Login function
unit LoginService;
interface
uses
XData.Service.Common;
type
[ServiceContract]
ILoginService = interface(IInvokable)
['{78F7B6F6-863F-4DCE-A4EA-95C16772600B}']
function Login(const User, Password: string): string;
end;
implementation
end.
unit LoginServiceImplementation;
interface
uses
XData.Server.Module,
XData.Service.Common,
LoginService;
type
[ServiceImplementation]
TLoginService = class(TInterfacedObject, ILoginService)
public
function Login(const User, Password: string): string;
end;
implementation
uses
Bcl.JOSE.Core.Builder,
Bcl.JOSE.Core.JWT,
XData.Sys.Exceptions;
{ TLoginService }
Const
JWT_SECRET = 'super_secret_0123456789_0123456789';
function TLoginService.Login(const User, Password: string): string;
var
JWT: TJWT;
Scopes: string;
begin
{ check if UserName and Password are valid, retrieve User data from database,
add relevant claims to JWT and return it. In this example, we will accept any
user as long the password is the same }
if User <> Password then
raise EXDataHttpUnauthorized.Create('Invalid password');
// Generate the token
JWT := TJWT.Create(TJWTClaims);
try
JWT.Claims.SetClaimOfType<string>('username', User);
JWT.Claims.Issuer := 'XData Server';
Result := TJOSE.SHA256CompactToken(JWT_SECRET, JWT);
finally
JWT.Free;
end;
end;
initialization
RegisterServiceType(TLoginService);
end.
unit accesoServiceImplementation;
interface
uses
XData.Server.Module,
XData.Service.Common,
Generics.Collections,
Data.DB, FireDAC.Comp.Client, FireDAC.Stan.Param,
DM,
accesoService,
Sparkle.Security, XData.Sys.Exceptions;
type
[ServiceImplementation]
TaccesoService = class(TInterfacedObject, IaccesoService)
strict private
DB: TDataModule1;
function GetQuery: TFDQuery;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
property Query: TFDQuery read GetQuery;
public
function Getacceso_id(codigo: Integer): Tacceso;
function Getacceso_list: TList<Tacceso>;
end;
implementation
function TaccesoService.GetQuery: TFDQuery;
begin
Result := DB.FDQuery2;
end;
procedure TaccesoService.AfterConstruction;
begin
inherited;
DB := TDataModule1.Create(nil);
end;
procedure TaccesoService.BeforeDestruction;
begin
DB.Free;
inherited;
end;
function TaccesoService.Getacceso_id(codigo: Integer): Tacceso;
var
User: IUserIdentity;
begin
User := TXDataOperationContext.Current.Request.User;
if User = nil then
raise EXDataHttpUnauthorized.Create('User not authenticated');
if not (User.Claims.Exists('admin') and User.Claims['admin'].AsBoolean) then
raise EXDataHttpForbidden.Create('Not enough privileges');
Query.SQL.Text := 'SELECT * FROM ACESSO WHERE CODIGO = :codigo';
Query.ParamByName('codigo').AsInteger := codigo;
Query.Open;
if Query.IsEmpty then Exit(nil);
Result := Tacceso.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
Result.codigo := Query.FieldByName('codigo').AsInteger;
Result.usuario := Query.FieldByName('usuario').AsString;
Result.senha := Query.FieldByName('senha').AsString;
end;
function TaccesoService.Getacceso_list: TList<Tacceso>;
var
acceso: Tacceso;
User: IUserIdentity;
begin
User := TXDataOperationContext.Current.Request.User;
if User = nil then
raise EXDataHttpUnauthorized.Create('User not authenticated');
if not (User.Claims.Exists('admin') and User.Claims['admin'].AsBoolean) then
raise EXDataHttpForbidden.Create('Not enough privileges');
Result := TList<Tacceso>.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
Query.SQL.Text := 'SELECT codigo, usuario, senha FROM ACESSO ORDER BY usuario';
Query.Open;
while not Query.Eof do
begin
acceso := Tacceso.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(acceso);
Result.Add(acceso);
acceso.codigo := Query.FieldByName('codigo').AsInteger;
acceso.usuario := Query.FieldByName('usuario').AsString;
acceso.senha := Query.FieldByName('senha').AsString;
Query.Next;
end;
end;
initialization
RegisterServiceType(TaccesoService);
end.
unit accesoServiceImplementation;
interface
uses
XData.Server.Module,
XData.Service.Common,
Generics.Collections,
Data.DB, FireDAC.Comp.Client, FireDAC.Stan.Param,
DM,
accesoService;
type
[ServiceImplementation]
TaccesoService = class(TInterfacedObject, IaccesoService)
strict private
DB: TDataModule1;
function GetQuery: TFDQuery;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
property Query: TFDQuery read GetQuery;
public
function Getacceso_id(codigo: Integer): Tacceso;
function Getacceso_list: TList<Tacceso>;
end;
implementation
uses
Aurelius.Drivers.Interfaces, System.IOUtils,
Bcl.Jose.Core.JWT, Bcl.JOSE.Core.Builder,
XData.Sys.Exceptions, Sparkle.Middleware.Jwt, Sparkle.HttpSys.Server, LoginServiceImplementation;
function TaccesoService.GetQuery: TFDQuery;
begin
Result := DB.FDQuery2;
end;
procedure TaccesoService.AfterConstruction;
begin
inherited;
DB := TDataModule1.Create(nil);
end;
procedure TaccesoService.BeforeDestruction;
begin
DB.Free;
inherited;
end;
function TaccesoService.Getacceso_id(codigo: Integer): Tacceso;
var
User: IUserIdentity;
begin
User := TXDataOperationContext.Current.Request.User;
if User = nil then
raise EXDataHttpUnauthorized.Create('User not authenticated');
if not (User.Claims.Exists('admin') and User.Claims['admin'].AsBoolean) then
raise EXDataHttpForbidden.Create('Not enough privileges');
Query.SQL.Text := 'SELECT * FROM ACESSO WHERE CODIGO = :codigo';
Query.ParamByName('codigo').AsInteger := codigo;
Query.Open;
if Query.IsEmpty then Exit(nil);
Result := Tacceso.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
Result.codigo := Query.FieldByName('codigo').AsInteger;
Result.usuario := Query.FieldByName('usuario').AsString;
Result.senha := Query.FieldByName('senha').AsString;
end;
function TaccesoService.Getacceso_list: TList<Tacceso>;
var
acceso: Tacceso;
User: IUserIdentity;
begin
Result := TList<Tacceso>.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
Query.SQL.Text := 'SELECT codigo, usuario, senha FROM ACESSO ORDER BY usuario';
Query.Open;
while not Query.Eof do
begin
acceso := Tacceso.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(acceso);
Result.Add(acceso);
acceso.codigo := Query.FieldByName('codigo').AsInteger;
acceso.usuario := Query.FieldByName('usuario').AsString;
acceso.senha := Query.FieldByName('senha').AsString;
Query.Next;
end;
end;
initialization
RegisterServiceType(TaccesoService);
end.