Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IW cant Handle Authentication Header
#1
Bug 
Request with header
Code:
Authorization: Bearer ACCESS_TOKEN

report Unsupport Authorization xxxx

waht  can i do?
Reply
#2
Please provide more context.
Reply
#3
(06-17-2021, 03:17 PM)kudzu Wrote: Please provide more context.

Create StandAlone(Indy) Webapplication
Run It

Then Make a Request like {Can User Httpdebug Tool Like Fiddler}

Code:
GET http://127.0.0.1:8088/ HTTP/1.1
User-Agent: Fiddler
Authorization: Bearer ACCESS_TOKEN
Host: 127.0.0.1:8088

Then Application will Report

Quote:Project Project1.exe raised exception class EInHTTPUnsupportedAuthorisationScheme with message 'Unsupported authorization scheme.'.

Any ServerControl Event is Trick
Reply
#4
(06-17-2021, 03:17 PM)kudzu Wrote: Please provide more context.

The Problem is From Indy

How Can I get Server in IW,Then Set OnParseAuthentication Event Will be Ok
Reply
#5
(06-17-2021, 06:01 PM)yonghu058 Wrote: Project Project1.exe raised exception class EInHTTPUnsupportedAuthorisationScheme with message 'Unsupported authorization scheme.'.

TIdHTTPServer implements native support for only BASIC authentication.  For other authentications, you need to use the TIdHTTPServer.OnParseAuthentication event to handle them manually, eg:

Code:
procedure TMyForm.IdHTTPServer1ParseAuthentication(AContext: TIdContext;
  const AAuthType, AAuthData: String; var VUsername, VPassword: String;
  var VHandled: Boolean);
begin
  if TextIsSame(AAuthType, 'Bearer') then begin
    VUsername := '';
    VPassword := AAuthData;
    VHandled := True;
  end;
end;

And then your TIdHTTPServer.OnCommand... event handlers can use the token stored in ARequestInfo.AuthPassword as needed (if ARequestInfo.AuthExists = True).

Currently, there is no way for TIdHTTPRequestInfo to specify which auth type the client requested.  If you need that info outside of your OnParseAuthentication event handler, it will need to store that info manually in the provided TIdContext. There are two ways to handle that:

- using the TIdContext.Data property, eg:

Code:
type
  TMyContextData = class
  public
    AuthType: string;
    ...
  end;

procedure TMyForm.IdHTTPServer1ParseAuthentication(AContext: TIdContext;
  const AAuthType, AAuthData: String; var VUsername, VPassword: String;
  var VHandled: Boolean);
begin
  if AContext.Data = nil then begin
    AContext.Data := TMyContextData.Create;
  end;
  TMyContextData(AContext.Data).AuthType := AAuthType;
  if TextIsSame(AAuthType, 'Bearer') then begin
    VUsername := '';
    VPassword := AAuthData;
    VHandled := True;
  end;
end;

procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  ...
  if ARequestInfo.AuthExists and (AContext.Data <> nil) then begin
    case PosInStrArray(TMyContextData(AContext.Data).AuthType, ['Bearer', 'Basic', ...], False) of
      0: begin
        // use ARequestInfo.AuthPassword as needed...
      end;
      1: begin
        // use ARequestInfo.AuthUsername and ARequestInfo.AuthPassword as needed ...
      end;
      ...
    end;
  end;
  ...
end;

- deriving a new class from TIdServerContext, adding custom fields/properties to it, and then assigning its type to the TIdHTTPServer.ContextClass property, eg:

Code:
type
  TMyContext = class(TIdServerContext)
  public
    AuthType: string;
    ...
  end;

procedure TMyForm.FormCreate(Sender: TObject);
begin
  // must be set before the server is activated...
  IdHTTPServer1.ContextClass := TMyContext;
end;

procedure TMyForm.IdHTTPServer1ParseAuthentication(AContext: TIdContext;
  const AAuthType, AAuthData: String; var VUsername, VPassword: String;
  var VHandled: Boolean);
begin
  TMyContext(AContext).AuthType := AAuthType;
  if TextIsSame(AAuthType, 'Bearer') then begin
    VUsername := '';
    VPassword := AAuthData;
    VHandled := True;
  end;
end;

procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  ...
  if ARequestInfo.AuthExists then begin
    case PosInStrArray(TMyContext(AContext).AuthType, ['Bearer', 'Basic', ...], False) of
      0: begin
        // use ARequestInfo.AuthPassword as needed...
      end;
      1: begin
        // use ARequestInfo.AuthUsername and ARequestInfo.AuthPassword as needed ...
      end;
      ...
    end;
  end;
  ...
end;

Reply
#6
I want Use Intraweb .  How Can I Use Intraweb to do like above
I want Let Intraweb(standalone Indy) to accept it.How Can i Do?
Reply
#7
(06-18-2021, 05:22 PM)yonghu058 Wrote: I want Use Intraweb .  How Can I Use Intraweb to do like above
I want Let Intraweb(standalone Indy) to accept it.How Can i Do?

That, I can't answer, sorry. I am not familiar with IntraWeb's architecture, or have access to its source code.

Reply
#8
(06-18-2021, 11:01 PM)rlebeau Wrote:
(06-18-2021, 05:22 PM)yonghu058 Wrote: I want Use Intraweb .  How Can I Use Intraweb to do like above
I want Let Intraweb(standalone Indy) to accept it.How Can i Do?

That, I can't answer, sorry.  I am not familiar with IntraWeb's architecture, or have access to its source code.

Thank You Anyway
Reply
#9
No body know?
Reply
#10
I'll need some time to investigate this. Maybe we can expose the OnParseAuthentication event, but I'm not sure yet.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)