IdAuthentication.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10071: IdAuthentication.pas
  11. {
  12. { Rev 1.1 01.2.2003 ã. 11:52:14 DBondzhev
  13. }
  14. {
  15. { Rev 1.0 2002.11.12 10:30:26 PM czhower
  16. }
  17. {
  18. Implementation of the Basic authentication as specified in
  19. RFC 2616
  20. Copyright: (c) Chad Z. Hower and The Winshoes Working Group.
  21. Author: Doychin Bondzhev ([email protected])
  22. Modified:
  23. 2001-Sep-11 : DSiders
  24. Corrected spelling for EIdAlreadyRegisteredAuthenticationMethod
  25. }
  26. unit IdAuthentication;
  27. interface
  28. Uses
  29. Classes, IdHeaderList, IdGlobal, IdException;
  30. Type
  31. TIdAuthenticationSchemes = (asBasic, asDigest, asNTLM, asUnknown);
  32. TIdAuthSchemeSet = set of TIdAuthenticationSchemes;
  33. TIdAuthWhatsNext = (wnAskTheProgram, wnDoRequest, wnFail);
  34. TIdAuthentication = class(TPersistent)
  35. protected
  36. FAuthRetries: Integer;
  37. FCurrentStep: Integer;
  38. FParams: TIdHeaderList;
  39. FAuthParams: TIdHeaderList;
  40. function ReadAuthInfo(AuthName: String): String;
  41. function DoNext: TIdAuthWhatsNext; virtual; abstract;
  42. procedure SetAuthParams(AValue: TIdHeaderList);
  43. function GetPassword: String;
  44. function GetUserName: String;
  45. function GetSteps: Integer; virtual;
  46. procedure SetPassword(const Value: String); virtual;
  47. procedure SetUserName(const Value: String); virtual;
  48. public
  49. constructor Create; virtual;
  50. destructor Destroy; override;
  51. procedure Reset; virtual;
  52. function Authentication: String; virtual; abstract;
  53. function KeepAlive: Boolean; virtual; abstract;
  54. function Next: TIdAuthWhatsNext;
  55. property AuthRetries: Integer read FAuthRetries;
  56. property AuthParams: TIdHeaderList read FAuthParams write SetAuthParams;
  57. property Params: TIdHeaderList read FParams;
  58. property Username: String read GetUserName write SetUserName;
  59. property Password: String read GetPassword write SetPassword;
  60. property Steps: Integer read GetSteps;
  61. property CurrentStep: Integer read FCurrentStep;
  62. end;
  63. TIdAuthenticationClass = class of TIdAuthentication;
  64. TIdBasicAuthentication = class(TIdAuthentication)
  65. protected
  66. FRealm: String;
  67. function DoNext: TIdAuthWhatsNext; override;
  68. function GetSteps: Integer; override; // this function determines the number of steps that this
  69. // Authtentication needs take to suceed;
  70. public
  71. constructor Create; override;
  72. function Authentication: String; override;
  73. function KeepAlive: Boolean; override;
  74. procedure Reset; override;
  75. property Realm: String read FRealm write FRealm;
  76. end;
  77. EIdAlreadyRegisteredAuthenticationMethod = class(EIdException);
  78. { Support functions }
  79. procedure RegisterAuthenticationMethod(MethodName: String; AuthClass: TIdAuthenticationClass);
  80. function FindAuthClass(AuthName: String): TIdAuthenticationClass;
  81. implementation
  82. Uses
  83. IdCoderMIME, IdResourceStrings, SysUtils;
  84. Type
  85. TAuthListObject = class(TObject)
  86. Auth: TIdAuthenticationClass;
  87. end;
  88. Var
  89. AuthList: TStringList = nil;
  90. procedure RegisterAuthenticationMethod(MethodName: String; AuthClass: TIdAuthenticationClass);
  91. Var
  92. LAuthItem: TAuthListObject;
  93. begin
  94. if not Assigned(AuthList) then begin
  95. AuthList := TStringList.Create;
  96. end;
  97. if AuthList.IndexOf(MethodName) < 0 then begin
  98. LAuthItem := TAuthListObject.Create;
  99. LAuthItem.Auth := AuthClass;
  100. AuthList.AddObject(MethodName, LAuthItem);
  101. end
  102. else begin
  103. raise EIdAlreadyRegisteredAuthenticationMethod.Create(Format(RSHTTPAuthAlreadyRegistered,
  104. [TAuthListObject(AuthList.Objects[AuthList.IndexOf(MethodName)]).Auth.ClassName]));
  105. end;
  106. end;
  107. function FindAuthClass(AuthName: String): TIdAuthenticationClass;
  108. begin
  109. if AuthList.IndexOf(AuthName) = -1 then
  110. result := nil
  111. else
  112. result := TAuthListObject(AuthList.Objects[AuthList.IndexOf(AuthName)]).Auth;
  113. end;
  114. { TIdAuthentication }
  115. constructor TIdAuthentication.Create;
  116. begin
  117. inherited Create;
  118. FParams := TIdHeaderList.Create;
  119. FCurrentStep := 0;
  120. end;
  121. destructor TIdAuthentication.Destroy;
  122. begin
  123. FreeAndNil(FAuthParams);
  124. FreeAndNil(FParams);
  125. inherited Destroy;
  126. end;
  127. procedure TIdAuthentication.SetAuthParams(AValue: TIdHeaderList);
  128. begin
  129. if not Assigned(FAuthParams) then begin
  130. FAuthParams := TIdHeaderList.Create;
  131. end;
  132. FAuthParams.Assign(AValue);
  133. end;
  134. function TIdAuthentication.ReadAuthInfo(AuthName: String): String;
  135. Var
  136. i: Integer;
  137. begin
  138. if Assigned(FAuthParams) then begin
  139. for i := 0 to FAuthParams.Count - 1 do begin
  140. if IndyPos(AuthName, FAuthParams[i]) = 1 then begin
  141. result := FAuthParams[i];
  142. exit;
  143. end;
  144. end;
  145. end
  146. else begin
  147. result := ''; {Do not Localize}
  148. end;
  149. end;
  150. function TIdAuthentication.Next: TIdAuthWhatsNext;
  151. begin
  152. result := DoNext;
  153. end;
  154. procedure TIdAuthentication.Reset;
  155. begin
  156. FAuthRetries := 0;
  157. end;
  158. function TIdAuthentication.GetPassword: String;
  159. begin
  160. result := Params.Values['password']; {Do not Localize}
  161. end;
  162. function TIdAuthentication.GetUserName: String;
  163. begin
  164. result := Params.Values['username']; {Do not Localize}
  165. end;
  166. procedure TIdAuthentication.SetPassword(const Value: String);
  167. begin
  168. Params.Values['Password'] := Value; {Do not Localize}
  169. end;
  170. procedure TIdAuthentication.SetUserName(const Value: String);
  171. begin
  172. Params.Values['Username'] := Value; {Do not Localize}
  173. end;
  174. function TIdAuthentication.GetSteps: Integer;
  175. begin
  176. result := 0;
  177. end;
  178. { TIdBasicAuthentication }
  179. constructor TIdBasicAuthentication.Create;
  180. begin
  181. inherited Create;
  182. FCurrentStep := 0;
  183. end;
  184. function TIdBasicAuthentication.Authentication: String;
  185. begin
  186. result := 'Basic ' {do not localize}
  187. + TIdEncoderMIME.EncodeString(Username + ':' + Password); {do not localize}
  188. end;
  189. function TIdBasicAuthentication.DoNext: TIdAuthWhatsNext;
  190. Var
  191. S: String;
  192. begin
  193. result := wnDoRequest;
  194. S := ReadAuthInfo('Basic'); {Do not Localize}
  195. Fetch(S);
  196. while Length(S) > 0 do
  197. with Params do begin
  198. // realm have 'realm="SomeRealmValue"' format {Do not Localize}
  199. // FRealm never assigned without StringReplace
  200. Add(StringReplace(Fetch(S, ', '), '=', NameValueSeparator, [])); {do not localize}
  201. end;
  202. FRealm := Copy(Params.Values['realm'], 2, Length(Params.Values['realm']) - 2); {Do not Localize}
  203. case FCurrentStep of
  204. 0: begin
  205. if (Length(Username) > 0) {and (Length(Password) > 0)} then begin
  206. result := wnDoRequest;
  207. end
  208. else begin
  209. result := wnAskTheProgram;
  210. end;
  211. Inc(FAuthRetries);
  212. end;
  213. 1: begin
  214. result := wnFail;
  215. end;
  216. end;
  217. end;
  218. function TIdBasicAuthentication.KeepAlive: Boolean;
  219. begin
  220. result := false;
  221. end;
  222. procedure TIdBasicAuthentication.Reset;
  223. begin
  224. inherited Reset;
  225. FCurrentStep := 0;
  226. end;
  227. function TIdBasicAuthentication.GetSteps: Integer;
  228. begin
  229. result := 1;
  230. end;
  231. initialization
  232. RegisterAuthenticationMethod('Basic', TIdBasicAuthentication); {Do not Localize}
  233. finalization
  234. if Assigned(AuthList) then begin
  235. while AuthList.Count > 0 do begin
  236. AuthList.Objects[0].Free;
  237. AuthList.Delete(0);
  238. end;
  239. AuthList.Free;
  240. end;
  241. end.