Creating a custom Authenticator #30
-
|
Hello, Iam trying to create a custom Authenticator for Token Authentification, but I have a hard time doing so. As I understand it, I need to implement the AuthenticatorIntf and the authenticate function. Within this function I need to construct the AuthInfo Object and the AuthenticatedUser, eg TokenAuthUser. I also need to create a new HttpSession with req->getSession(TRUE). This is a point where I get a Memory fault. When using the other Authenticator everything works fine, but they require me to use username:password for example when using BasicAuthenticator. So the question is, how do I properly implement my own custom Authenticator. Im running this Server on a QNX7.1 platform. With kind regards Here is the code I have so far AuthenticatedUser* TokenAuthenticator::authenticate(AuthenticatorIntf* super, const char * relPath, HttpCommand * cmd)
{
TokenAuthenticator* self = (TokenAuthenticator*)super;
HttpRequest * req = cmd->getRequest();
AuthInfo authInfo;
// check if already a authenticated session exists
printf("check if already a authenticated session exists\n");
HttpSession * session = req->getSession(FALSE);
if (session)
{
AuthenticatedUser * user = AuthenticatedUser::get(session);
if (user)
{
return user;
}
}
AuthInfo_constructor(&authInfo, 0, cmd, AuthenticatedUserType_Token); // I Added a new AuthenticatedUserType in AuthenticatedUser.h
// also adjusted the references in BAS.c
// check for the correct Header and get the value
printf("check for the correct Header and get the value\n");
const char* token = req->getHeaderValue("x-api-key"); // I have an additional header for the token
if (token)
{
TokenAuthUser* tokenAuthUser; // New struct, but looks like BasicAuthUser
// set token as username so UserDB uses it to verify
authInfo.username = token;
// get auth user list from server
printf("get auth user list from server\n");
authInfo.authUserList = cmd->getServer()->getAuthUserList(token);
// ask the UserIntf to check the api token
printf("ask the UserIntf to check the api token\n");
self->userDB->getPwdFp(self->userDB, &authInfo);
if (authInfo.ct != AuthInfoCT::AuthInfoCT_Valid)
{
self->loginResp->serviceFp(self->loginResp, &authInfo);
AuthUserList_termIfEmpty(authInfo.authUserList);
// TokenAuthenticator::termIfEmpty(authInfo.authUserList);
return 0;
}
// AuthUSerList createOrCheck (BAS.c Line 80139)
printf("AuthUserList createOrCheck\n");
if (AuthUserList_createOrCheck(&authInfo, self->userDB, (void**)&tokenAuthUser, sizeof(TokenAuthUser)))
{
// somethings gone wrong
printf("somethings gone wrong\n");
self->loginResp->serviceFp(self->loginResp, &authInfo);
AuthUserList_termIfEmpty(authInfo.authUserList);
// TokenAuthenticator::termIfEmpty(authInfo.authUserList);
return 0;
}
// create new Authenticated user with TokenAuthUser and AuthInfo
printf("create new Authenticated user with TokenAuthUser and AuthInfo\n");
// using "TAU" here for TokenAuthUser
AuthenticatedUser_constructor((AuthenticatedUser*)&tokenAuthUser, "TAU", authInfo.authUserList, (HttpSessionAttribute_Destructor)destruct);
authInfo.user = (AuthenticatedUser*)&tokenAuthUser;
// get Session and set user as attribute
printf("get Session and set user as attribute\n");
// !!!!!!!!!!!!!! here I get the Memory fault !!!!!!!!!!!!!!!!!!!
session = req->getSession(TRUE);
printf("check session\n");
bool er = false;
if (!session)
{
er = true;
printf("ERROR: No session\n");
}
if (session->setAttribute((HttpSessionAttribute*)&tokenAuthUser))
{
er = true;
printf("ERROR: session->setAttribute failed\n");
}
if (!AuthenticatedUser::get(session))
{
er = true;
printf("ERROR: Could not fetch Authenticated User from session\n");
}
if (er)
{
// somethings gone wrong
printf("somethings gone wrong\n");
self->loginResp->serviceFp(self->loginResp, &authInfo);
AuthUserList_termIfEmpty(authInfo.authUserList);
// TokenAuthenticator::termIfEmpty(authInfo.authUserList);
return 0;
}
return (AuthenticatedUser*)&tokenAuthUser;
}
printf("No token. Exit\n");
self->loginResp->serviceFp(self->loginResp, &authInfo);
AuthUserList_termIfEmpty(authInfo.authUserList);
// TokenAuthenticator::termIfEmpty(authInfo.authUserList);
return 0;
}
// used for the AuthenticatedUser_constructor
void TokenAuthenticator::destruct(TokenAuthUser* o)
{
printf("void TokenAuthenticator::destruct(TokenAuthUser* o)\n");
AuthenticatedUser_destructor((AuthenticatedUser*)o);
baFree(o);
}
|
Beta Was this translation helpful? Give feedback.
Replies: 5 comments
-
|
The issue stems from the use of the non-public AuthUserList_createOrCheck function. It cannot be used in the way you're attempting, and this misuse leads to a crash inside AuthenticatedUser_constructor. We recommend implementing your custom token-based authenticator in Lua instead. The Barracuda App Server provides all the required features for token authentication in Lua, and it's the supported approach for custom authentication logic. You can find working examples here: https://realtimelogic.com/ba/doc/en/authentication.html#example |
Beta Was this translation helpful? Give feedback.
-
|
Ok, thanks. Iam checking it out! |
Beta Was this translation helpful? Give feedback.
-
|
Hello, I checked out the tutorials, but I cant seem to find one, thats actually implementing a custom Authenticator. They are all using the ba.create.authenticator function and using one of the predefined authenticator types, for example basic or auth. I also read that these authenticators are using the c implementation. What I am trying to achieve is to create a rest api with the BAS and I cant really see how I should do this in Lua with the lua server pages, because they seem to be designed to send html back to the client, when html is often not what I want. In the c++ code I can extend my classes with HttpPage or HttpDir and overwrite the service function to implement my rest api logic. There I dont need the html. So this works fine for me. But I want to be able to create a token authentication method and maybe some other custom method in the future. So the question is either how do I create a TokenAuthenticator class in c++ (or maybe I have to do it in c and extend BAS.c?) or how do I use the lua server pages to implement a rest api (and also how do I do token authentication, because I couldnt find a custom authenticator)? Maybe I dont understand something crutial in the lua examples. Maybe there are examples and I just dont see that they do what I want? Help would be much appreciated. Thank you! |
Beta Was this translation helpful? Give feedback.
-
|
Your REST API concern: while Lua directory functions and LSP are often used to generate HTML, they are not limited to HTML at all. In fact, when using directory functions or LSP, you can return JSON, XML, binary, or whatever content type you need. LSP is just a mechanism; it's up to you how you use it. The ba.create.authenticator function in Lua wraps the underlying C implementation and gives you full control over how authentication is performed, including implementing your own token-based logic. You don't need to create a "custom authenticator class" like in C++; instead, you write a handler (a Lua function or directory object) that implements your own authentication logic before executing protected routes. Examples that use custom auth: Single Sign-On, Passwordless Authentication with WebAuthn, RADIUS Authentication, OAuth 2.0 Authentication. I cannot be more specific since I do not know how you intend your custom authenticator to work. Since you're working on a commercial product and deploying on QNX, we strongly recommend reaching out to Real Time Logic to set up a support agreement. This will give you direct access to expert assistance, ensure you're following best practices, and help you avoid pitfalls |
Beta Was this translation helpful? Give feedback.
-
|
Thank you very much for the additional information. I'll try it out! |
Beta Was this translation helpful? Give feedback.
Your REST API concern: while Lua directory functions and LSP are often used to generate HTML, they are not limited to HTML at all. In fact, when using directory functions or LSP, you can return JSON, XML, binary, or whatever content type you need. LSP is just a mechanism; it's up to you how you use it.
Directory functions: https://realtimelogic.com/ba/doc/en/VirtualFileSystem.html#directory
The ba.create.authenticator function in Lua wraps the underlying C implementation and gives you full control over how authentication is performed, including implementing your own token-based logic. You don't need to create a "custom authenticator class" like in C++; instead, you write a handler (a Lua …