File Information
Library: OSP/Auth/Data
Package: Auth
Header: Poco/OSP/Auth/Data/AuthAdminServiceImpl.h
Description
This class implements the AuthAdminService using a SQL database accessed via the POCO Data library, and optionally LDAP for password verification and permissions.
Upon successful authentication of a user, the class will cache the permissions for the user so that further permission checks are very quick.
This implementation supports multiple variants/versions of storing password hashes.
- Version 1 is the original mechanism, using MD5 with a global salt. This is no longer considered secure and should no longer be used.
- Version 2 uses PBKDF2 with HMAC-SHA1 and per-user random salt.
- Version 3 uses PBKDF2 with HMAC-SHA1 and per-user random salt with additional MD5 password pre-hashing, allowing implementation of secure challenge-response authentication mechanisms such as SCRAM-SHA1.
- Version 4 uses PBKDF2 with HMAC-SHA256, SHA1 pre-hasing and a minimum of 50.000 iterations, and a minimum salt length of 8 bytes.
Version 4 is recommended for new deployments. Stored passwords using a lower version than the one configured will automatically be upgraded as soon as a user successfully authenticates.
As of 2021, the recommended number of iterations for PBKDF2 with HMAC-SHA256 is 310.000 for HMAC-SHA256 (version 4) and 720.000 for HMAC-SHA1 (version 3). See https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html for more information.
Versions 3 and 4 pass a hash of the password rather than the actual password to the PBKDF2 hashing function. This is to guard against certain timing attacks that would allow an attacker to get hints regarding the password length, and also to avoid excessive CPU usage in case of very long passwords.
Note that the getUserAttribute() method of this implementation supports the following special attributes:
- $salt: Returns the salt used for hashing the given user's password. For Version 1, this will be the configured global salt string. For Version 2, this will be a string consisting entirely of hexadecimal digits. For Versions 3 and 4, this will be a string containing binary data.
- $iterations: Returns the number of PBKDF2 iterations used for hashing the given user's password.
- $hash: Returns the password hash stored for the given user. For Versions 1 and 2, this will be a string consisting entirely of hexadecimal digits. For Versions 3 and 4, this will be a string containing binary data.
- $version: Returns the version of the hash used for the given user.
Inheritance
Direct Base Classes: Poco::OSP::Auth::AbstractLDAPAuthAdminService
All Base Classes: Poco::OSP::Auth::AbstractLDAPAuthAdminService, Poco::OSP::Auth::AuthAdminService, Poco::OSP::Auth::AuthService, Poco::OSP::Service, Poco::RefCountedObject
Member Summary
Member Functions: addRole, addUser, addUserImpl, assignRoleToUser, attributesForUser, authenticate, authenticateDB, authorize, authorizeRole, changePassword, changePasswordImpl, checkDatabaseConnectivity, createOrUpdateUserImpl, discoverInlineAttributes, effectivePermissionsForUser, findUsersByAttribute, getUserAttribute, grantPermissionsToRole, grantPermissionsToUser, invalidateCaches, isA, isExternalUser, isUserLockedOut, lockOutUser, permissionsForRole, permissionsForUser, removeRole, removeRoleFromUser, removeUser, removeUserAttribute, removeUserImpl, replacePermissionsForRole, replacePermissionsForUser, replacePermissionsForUserImpl, replaceRolesForUser, replaceRolesForUserImpl, replaceUserAttributeImpl, replaceUserAttributes, reset, revokePermission, revokePermissionsFromRole, revokePermissionsFromUser, roleExists, roleExistsImpl, roles, rolesForUser, session, sessionExpired, setUserAttribute, setupSession, type, uncacheUser, uncacheUserImpl, unlockOutUser, updateUserAttributes, userEnabled, userExists, userExistsImpl, users, usersWithAttribute, usersWithName, usersWithPermission, usersWithRole
Inherited Functions: addRole, addUser, assignRoleToUser, attributesForUser, authenticate, authenticateLDAP, authorize, changePassword, createOrUpdateUserImpl, duplicate, effectivePermissionsForUser, escapeLDAP, findUsersByAttribute, getUserAttribute, grantPermissionsToRole, grantPermissionsToUser, invalidateCaches, isA, isExternalUser, isExtraAttribute, isUserLockedOut, lockOutUser, permissionsForRole, permissionsForUser, referenceCount, release, removeRole, removeRoleFromUser, removeUser, removeUserAttribute, replacePermissionsForRole, replacePermissionsForUser, replacePermissionsForUserImpl, replaceRolesForUser, replaceRolesForUserImpl, replaceUserAttributeImpl, replaceUserAttributes, reset, revokePermission, revokePermissionsFromRole, revokePermissionsFromUser, roleExists, roles, rolesForUser, setUserAttribute, type, uncacheUser, unlockOutUser, updateUserAttributes, userEnabled, userExists, users, usersWithAttribute, usersWithName, usersWithPermission, usersWithRole
Nested Classes
struct AuthParams
Types Aliases
Ptr
using Ptr = Poco::AutoPtr < AuthAdminServiceImpl >;
Enumerations
Anonymous
V4_MIN_ITERATIONS = 50000
Anonymous
SQL_CACHE_BUCKET_SIZE = 113
Constructors
AuthAdminServiceImpl
AuthAdminServiceImpl(
const Poco::Util::AbstractConfiguration & properties,
Poco::Logger & logger,
const AuthParams & authParams,
const LDAPParams & ldapParams
);
Creates the AuthAdminServiceImpl using the given authentication and LDAP parameters.
Note: if ldapParams.uri is empty, LDAP authentication will be disabled.
See the Poco::Data::Session class for more information on connector names and connection strings.
Destructor
~AuthAdminServiceImpl
Destroys the AuthAdminServiceImpl.
Member Functions
addRole
void addRole(
const std::string & rolename
);
addUser
void addUser(
const std::string & username,
const std::string & password
);
assignRoleToUser
void assignRoleToUser(
const std::string & username,
const std::string & rolename
);
attributesForUser
void attributesForUser(
const std::string & username,
std::set < std::string > & attributes
) const;
attributesForUser
void attributesForUser(
const std::string & username,
std::map < std::string, std::string > & attributes
) const;
authenticate
bool authenticate(
const std::string & username,
const std::string & credentials
) const;
authorize
bool authorize(
const std::string & username,
const std::string & permission
) const;
authorize
bool authorize(
const std::string & userName,
const std::string & roleOrScope,
const std::string & permission
) const;
changePassword
void changePassword(
const std::string & username,
const std::string & password
);
checkDatabaseConnectivity
static bool checkDatabaseConnectivity(
const Poco::Util::AbstractConfiguration & properties,
const AuthParams & authParams,
Poco::Logger & logger
);
Checks whether the database connection is ok.
effectivePermissionsForUser
void effectivePermissionsForUser(
const std::string & username,
std::set < std::string > & permissions
) const;
findUsersByAttribute
std::vector < std::string > findUsersByAttribute(
const std::string & attribute,
const std::string & value
) const;
getUserAttribute
std::string getUserAttribute(
const std::string & username,
const std::string & attribute,
const std::string & deflt = std::string ()
) const;
grantPermissionsToRole
void grantPermissionsToRole(
const std::string & rolename,
const std::set < std::string > & permissions
);
grantPermissionsToUser
void grantPermissionsToUser(
const std::string & username,
const std::set < std::string > & permissions
);
invalidateCaches
void invalidateCaches(
int what = INVALIDATE_ALL
);
isA
bool isA(
const std::type_info & otherType
) const;
See also: Poco::OSP::Auth::AuthAdminService::isA()
isExternalUser
bool isExternalUser(
const std::string & username
) const;
isUserLockedOut
bool isUserLockedOut(
const std::string & username
) const;
lockOutUser
void lockOutUser(
const std::string & username,
const Poco::DateTime & lockOutUntil
);
permissionsForRole
void permissionsForRole(
const std::string & rolename,
std::set < std::string > & permissions
) const;
permissionsForUser
void permissionsForUser(
const std::string & username,
std::set < std::string > & permissions
) const;
removeRole
void removeRole(
const std::string & rolename
);
removeRoleFromUser
void removeRoleFromUser(
const std::string & username,
const std::string & rolename
);
removeUser
void removeUser(
const std::string & username
);
removeUserAttribute
void removeUserAttribute(
const std::string & username,
const std::string & attribute
);
replacePermissionsForRole
void replacePermissionsForRole(
const std::string & rolename,
const std::set < std::string > & permissions
);
replacePermissionsForUser
void replacePermissionsForUser(
const std::string & username,
const std::set < std::string > & permissions
);
replaceRolesForUser
void replaceRolesForUser(
const std::string & username,
const std::set < std::string > & permissions
);
replaceUserAttributes
void replaceUserAttributes(
const std::string & username,
const std::map < std::string, std::string > & attributes
);
reset
void reset();
revokePermission
void revokePermission(
const std::string & permission
);
revokePermissionsFromRole
void revokePermissionsFromRole(
const std::string & rolename,
const std::set < std::string > & permissions
);
revokePermissionsFromUser
void revokePermissionsFromUser(
const std::string & username,
const std::set < std::string > & permissions
);
roleExists
bool roleExists(
const std::string & rolename
) const;
roles
void roles(
std::set < std::string > & roles
) const;
rolesForUser
void rolesForUser(
const std::string & username,
std::set < std::string > & roles
) const;
setUserAttribute
void setUserAttribute(
const std::string & username,
const std::string & attribute,
const std::string & value
);
type
const std::type_info & type() const;
uncacheUser
void uncacheUser(
const std::string & username
);
unlockOutUser
void unlockOutUser(
const std::string & username
);
updateUserAttributes
void updateUserAttributes(
const std::string & username,
const std::map < std::string, std::string > & attributes
);
userEnabled
bool userEnabled(
const std::string & username
) const;
userExists
bool userExists(
const std::string & username
) const;
users
int users(
std::set < std::string > & users,
int first = 0,
int limit = 0
) const;
usersWithAttribute
int usersWithAttribute(
std::set < std::string > & users,
const std::string & attribute,
const std::string & value,
int first = 0,
int limit = 0
) const;
usersWithName
int usersWithName(
std::set < std::string > & users,
const std::string & pattern,
int first = 0,
int limit = 0
) const;
usersWithPermission
int usersWithPermission(
std::set < std::string > & users,
const std::string & permission,
int first = 0,
int limit = 0
) const;
usersWithRole
int usersWithRole(
std::set < std::string > & users,
const std::string & role,
int first = 0,
int limit = 0
) const;
addUserImpl
void addUserImpl(
Poco::Data::Session & session,
const std::string & username,
const std::string & password
) const;
authenticateDB
bool authenticateDB(
Poco::Data::Session & session,
const std::string & username,
const std::string & credentials
) const;
authorizeRole
bool authorizeRole(
const std::string & rolename,
const std::string & permission
) const;
changePasswordImpl
void changePasswordImpl(
Poco::Data::Session & session,
const std::string & username,
const std::string & hashedCredentials
) const;
createOrUpdateUserImpl
void createOrUpdateUserImpl(
Poco::Data::Session & session,
const std::string & username,
const std::string & credentials
) const;
createOrUpdateUserImpl
void createOrUpdateUserImpl(
const std::string & username,
const std::string & credentials
) const;
discoverInlineAttributes
void discoverInlineAttributes();
removeUserImpl
void removeUserImpl(
Poco::Data::Session & session,
const std::string & username
) const;
replacePermissionsForUserImpl
void replacePermissionsForUserImpl(
Poco::Data::Session & session,
const std::string & username,
const std::set < std::string > & permissions
) const;
replacePermissionsForUserImpl
void replacePermissionsForUserImpl(
const std::string & username,
const std::set < std::string > & permissions
) const;
replaceRolesForUserImpl
void replaceRolesForUserImpl(
Poco::Data::Session & session,
const std::string & username,
const std::set < std::string > & permissions
) const;
replaceRolesForUserImpl
void replaceRolesForUserImpl(
const std::string & username,
const std::set < std::string > & permissions
) const;
replaceUserAttributeImpl
void replaceUserAttributeImpl(
Poco::Data::Session & session,
const std::string & username,
const std::string & attribute,
const std::string & value
) const;
replaceUserAttributeImpl
void replaceUserAttributeImpl(
const std::string & username,
const std::string & attribute,
const std::string & value
) const;
roleExistsImpl
bool roleExistsImpl(
Poco::Data::Session & session,
const std::string & rolename
) const;
session
Poco::Data::Session & session() const;
sessionExpired
bool sessionExpired() const;
setupSession
static void setupSession(
Poco::Data::Session & session,
const Poco::Util::AbstractConfiguration & properties,
const AuthParams & authParams,
Poco::Logger & logger
);
uncacheUserImpl
void uncacheUserImpl(
const std::string & username
) const;
userExistsImpl
bool userExistsImpl(
Poco::Data::Session & session,
const std::string & username
) const;
Variables
USER_ATTR_FAILURES
static const std::string USER_ATTR_FAILURES;
USER_ATTR_LDAP
static const std::string USER_ATTR_LDAP;
USER_ATTR_LOCKOUT
static const std::string USER_ATTR_LOCKOUT;