Perhaps we would have to check and validate the code after this change.
]]>In my opinion, there is no need to authorize each request, sufficient that the function Auth gave out the session identifier.
In this case, only one function (Auth) depends on the method of authentication, all other calls processed regardless of the manner in which the client is logged in.
The only problem - when the server restarted, and clients must re-authenticate.
For clients in Delphi this does TSQLRestClientURI.URI, but we need that re-authentication is performed for the AJAX client, too.
I wrote about integrated authentication (NTLM), there is no way to use javascript.
You are right.
I meant the "Digest" scheme only.
With NTLM it does make sense.
But it all cases, even NTLM can use a server-side nonce, since we implement it on our server side, right?
]]>unless you do it in JavaScript
I wrote about integrated authentication (NTLM), there is no way to use javascript.
]]>But the browser will not to do that.
... unless you do it in JavaScript, like with our mORMot scheme.
]]>This is what we do with the mORMot authentication scheme (with some additional steps/security points).
In all cases, there is a ConnectionID available now.
]]>I'm still not convinced about the ConnectionID parameter.
In current NTLM implementation we send SecCtxId as parameter to Auth function.
GET ModelRoot/auth?UserName=&id=<SecCtxId>&data=...
But if we use NTLM as it is used in browser-based authentication, there will be no place for SecCtxId.
So we need a way to distinguish clients before to authentication.
The same problem will be in any two-step authentication, like Digest.
To solve this problem, I propose to use ConnectionID.
In sample code http://synopse.info/forum/viewtopic.php?pid=5809#p5809 I use RemoteIP header to distinguish clients, but it is an unreliable method.
]]>Yes, I would like authentication/authorization classes/interfaces to be as generic as possible, i.e. as needed by TSQLRestServer.URI process, so allow resource access without no-predefined scheme, but still compliant with the current KISS implementation.
I'm still not convinced about the ConnectionID parameter.
I have implemented it - http://synopse.info/fossil/info/0636eeec54 - but am still a bit doubtful of its utility.
It does not make any problem to me to have several physical connections used for very same session.
For instance, it is how event notification may be implemented in the future (via websockets or long-pooling.
- ConnectionID parameter - http://synopse.info/fossil/info/0636eeec54
- Authentication classes - http://synopse.info/fossil/info/8c8a2a880c
- Authorization classes - http://synopse.info/fossil/info/7c079c49d6
In short, two new sets of class hierarchy will be available to set Authentication and Authorization, on purpose.
See http://technet.microsoft.com/en-us/library/cc759647
My proposal is to use some interfaces for it, so that we may be able to use remote services for both purposes.
I suspect the RegisterAuthenticationScheme() should be for the whole server
I also
Do several authentication schemes make sense?
I'm not sure that I understood correctly. If you mean:
TSQLRestServer.RegisterAuthenticationScheme('mORMot', TMoromAuth); // here I mean mORMot algorithm using HEADER
TSQLRestServer.RegisterAuthenticationScheme('Negotiate', TNegotiateAuth);
TSQLRestServer.RegisterAuthenticationScheme('Basic', TBasicAuth);
then yes - it make sense. In this case Delphi client choose mORMot, browser for domain user choose Negotiate (as more strong auth method) and for non-domain user - Basic
if you mean use mORMot-style (session_signature in URI) and header style auth in the same time - no, it not make sense as for me.
And from my POV here we need:
6. add connectionID attribute to TSQLRestServerURIParams ( for the http.sys server = Req^.ConnectionId, for socket-based = Int64(Socket), for namedPaper = Int64(GetNamedPipeClientProcessId/GetNamedPipeClientSessionId), for messages = Int64(window handle)
7. add event onUserAuth in witch I can check user credential and fill user GroupRights (I actually get a user groups from LDAP and associate it with group binary mask). See also http://synopse.info/forum/viewtopic.php?id=1218
]]>1. Handle RegisterAuthenticationScheme() with one dedicated class, for mORMot URL-level signature (i.e. current scheme) - this will stay the default;
2. Implement a new abstract authentication, parent for all HTTP header-level new mode;
3. Implement new authentication class for mORMot header-level signature;
4. Implement Basic authentication;
5. Implement Negotiate authentication.
In fact, Digest may be difficult to implement, since we stored the SHA-256 hash in the DB, and the Digest mode expects some MD5 hash.
I suspect the RegisterAuthenticationScheme() should be for the whole server - unless TSQLRestServer.ServiceMethodByPassAuthentication() is called for some particular methods.
We may be able to do it at the interface/method level (as some new TServiceMethodExecutionOption types?), but it may need some big code refactoring. Is it worth it?
Or one authentication scheme for all methods is a good option?
Do several authentication schemes make sense? In fact, for instance if we allow both BASIC and mORMot schemes at the same, it does not make sense to use mORMot style, unless you have a per-interface/per-method scheme.