You are not logged in.
Pages: 1
I am restarting this discussion in a new thread to cover the implementation of OAuth2. The original discussion was here.
I know there is at least some interest in this. My submission in the previous thread has gone quiet. Not sure if it's because my work is terrible, incomplete or both? I am hoping it is just because it is not immediately clear as to how to get OAuth2 up and running easily, and it is this that I will address in this discussion.
tldr; For the really impatient:
Get the core implemetation: OAuth2Authentication.pas
Include OAuth2Authentication.pas in you Delphi project
Derive a class from one of the 4 grant types:
TOAuth2AuthorizationGrant
TOAuth2ImplicitGrant
TOAuth2ResourceOwnerPasswordGrant - (example based on this one)
TOAuth2ClientCredentialsGrant
Override the minimum required methods:
GetAuthToken() - you validate credentials and return a token
GetSession() - you validate the token and return a TAuthSession (or descendant)
AuthSuccess() - you store the auth_token, refresh_token and expires for future use (authenticating subsequent requests)
//TODO: Refresh token handling goes here
In your TSQLRestServer (or descendant) constructor register your authentication class:
constructor TMySQLRestServer.Create(aModel: TSQLModel);
begin
inherited;
AuthenticationRegister([TMyAuthentication]);
end;
Incorporate the 3 changes below into mORMot.pas
The example
Let me first briefly outline my requirements. We use mORMot only as a server to provide json resources from an existing, large, legacy DB2 database. The client is an Android application but there is the expectation that the mORMot server with provide resources for other integration's. With that said I have done some pretty extensive modifications to the server (via descendants) to provide a flexible architecture for our developers to create new server (endpoints) and extend existing endpoints with additional resources.
Our system is also internal (for now) and is expected to operate within our customers corporate network (or VPN). This affects security considerations.
Authentication
Although the OAuth2 implementation is not complete, it follows the spec (https://tools.ietf.org/html/rfc6749) to the letter.
AFAIK, the OAuth2 authentication process is similar to the mORMot system.
The spec outlines 4 grant types. The first, Authorization Code Grant, is probably the most used for web site collaboration and the primary use case envisioned by the creators of this. However, in my situation I want to connect with an existing user/pass database and provide authentication tokens. This is a common pattern and is supported well on Android. OAuth2 provides 3 alternative grant types to support additional cases, after reviewing the grant types I decided on "Resource Owner Password Grant", IMHO this matches both our needs and matches the mORMot authentication system well.
The process occurs like so:
In order to access a resource the client must have an Authorization bearer token in the HTTP header e.g.:
AUTHORIZATION: Bearer FD94A9F2D4644F619CD3705B98371EF2
if this is not present the server will return "401 Unauthorized" (currently mORMot would produce 403 Forbidden). The header will contain a
WWW-Authenticate: Bearer realm="mORMot Server"
The body will contain a json document with 1 to 3 data elements:
{
error: "Unauthorized" //REQUIRED
error_description: "Something more descriptive" //OPTIONAL
error_uri: "uri for more info about this error" //OPTIONAL
}
In order to get a token the client must request a token at the /auth endpoint (same as mORMot?). Include a standard basic authentication header and also include the user/pass in the body (Obviously a secure connection is recommended for this). Personally I don't understand why they want the credentials twice. This implementation looks at the "Authorization: Basic ..." header only.
A successful call to /auth will result in something like:
{
"access_token": "0C49867F502F455CA300916F158E6CDB",
"token_type": "bearer",
"expires_in": 86400,
"refresh_token": "00F075FB3AE541E2984345CF88470A00"
}
The client should store that access_token and use it as the bearer token until another 401 is received at which point the refresh token logic should kick in.
I would like to make this a full and complete implementation. But... I am not going to bother if there is no interest. I expect to start the refresh token logic very soon. as for client support and other grant types, that will depend on interest.
Best regards,
Jeff
PS: Just realized there was something missing from my original post:
Add a new method to TSQLRestServerAuthentication (to allow each authentication class to handle failures individually)
TSQLRestServerAuthentication = class
...
public
...
function AuthenticationFailed(Ctxt: TSQLRestServerURIContext): boolean; virtual;
end;
is implemeted like so (to ensure backwards compatibility):
function TSQLRestServerAuthentication.AuthenticationFailed(Ctxt: TSQLRestServerURIContext): boolean;
begin
Ctxt.Call.OutStatus := HTML_FORBIDDEN;
Result := True;
end;
then in TSQLRestServerURIContext we modify AuthenticationFailed() to handle multiple authentication instances:
procedure TSQLRestServerURIContext.AuthenticationFailed;
var
aSession: TAuthSession;
i: integer;
begin
//JGB
if Server.HandleAuthentication then
begin
Session := CONST_AUTHENTICATION_SESSION_NOT_STARTED;
Server.fSessions.Lock;
try
aSession := nil;
if Server.fSessionAuthentication<>nil then
for i := 0 to Server.fSessionAuthentications.Count-1 do
if Server.fSessionAuthentication[i].AuthenticationFailed(Self) then
Break;
finally
Server.fSessions.UnLock;
end;
end;
// 401 Unauthorized response MUST include a WWW-Authenticate header,
// which is not what we used, so here we won't send 401 error code but 403
//JGB - We handle the out status in the TSQLRestServerAuthentication classes
//JGB - Call.OutStatus := HTML_FORBIDDEN;
end;
The TOAuth2AbstractAuthentication class uses this method to return authentication failures consistent with the OAuth2 spec.
Offline
Hi,
I am interested in this. I want to implement SSO Authentication using OAuth. please share some more detail on this.
Thanks & Regards
Purvarshi jain
Offline
1
Offline
I will work on OAuth2 this weekend.
Thanks for sharing.
@ab any progress ? Seems like OAuth2 work takes more than one weekend ;)
Last edited by hnb (2016-10-19 10:37:47)
best regards,
Maciej Izak
Offline
Has anyone done anything more with this ?
Offline
Almost, very close, I've got externalize authentication working for HTMl5/AJAX web clients. I've tested it with SAML and CAS, but I do not have a production OIDC server to ensure I've got it all working perfectly. My site is preparing an ADFS system which is in beta testing right now, and I hope to have completed against it by Christmas.
Erick
Offline
Does anybody still have copies of these gists available? I need a mormot server with oauth authentication and was hoping this would be something to build on. But the gists seem to be all gone already.
Offline
Does anybody still have copies of these gists available? I need a mormot server with oauth authentication and was hoping this would be something to build on. But the gists seem to be all gone already.
email sent
Offline
Thank you so much!
Offline
squirrel wrote:Does anybody still have copies of these gists available? I need a mormot server with oauth authentication and was hoping this would be something to build on. But the gists seem to be all gone already.
email sent
Hi there Prometheus,
Could you please send me the copies by email too?
Thanks a lot
JD
Offline
Email sent
Offline
Perhaps a new public gist may be more convenient.
..
The file is not mine, so I don't feel comfortable doing this
Offline
I world like a copy too please. Cannyou put on github?
Offline
Has anybody had any success implimenting this oauth2.0 into their project?
Offline
https://gist.github.com/jbendixsen/392e … cation-pas
The link is not working. Can someone send a OAuth2 (or JWT) implementation to mORMot?
Offline
Pages: 1