Windows AD Authentication - User Names with Spaces
WinCC OA AD authentication does not like this, because OA usernames do not support spaces.
So I have tried implementing UserDefined authentication to bridge the gap between these, and have got nearly everything working. The only thing that does not work is:
- if the user changes their password on the AD domain, then the user is unable to log on to WinCC OA any longer
To recover from this, I have to go in with PARA and poke the _Users datapoint so that WinCC OA does not recognise that user any more. Then, next time they log in, a new OA user is created for them.
Can anyone help me with this?
The mechanism I use is to ask the users to log in with underscore characters instead of spaces in their username (e.g. John_Smith), so WinCC OA has usernames without spaces.
I have inherited my UserDefined authentication class from the WinCC OA AD authentication class (OaAuthMethodAD). As far as possible, I try to call the function provided by that class. For instance, in my implementation of CheckUserPassword, I replace underscores in the username with spaces, and then call the OaAuthMethodAD implementation of CheckUserPassword. This successfully authenticates the username (which now includes spaces) against Active Directory. Active Directory group membership then successfully determines the privileges that the user has on the WinCC OA system.
But if the user changes their password on Active Directory, the user cannot then log on to WinCC OA. I can see that CheckUserPassword is correctly authenticating the user and their new password. My OaAuthMethodUserdefined::mustCreateUser function is then called, and I call OaAuthMethodAD::mustCreateUser. Curiously, this returns TRUE, although the user (john_smith) exists in WinCC OA. (Actually, the TRUE return happens whether the password has been changed or not). So I have to work out whether the user already exists and change the return to FALSE - otherwise I get the error message that the user cannot be created.
I can also see a call to OaAuthMethodUserdefined::getExternalIdForOSUser function, with a blank username. There is no problem with this, it seems to happen quite often and returns the SID for the Windows logged on user (not necessarily John Smith).
Then the login dialog displays an "Authentication error" popup. This is before any functions of UpdateUserGroups.ctl activate. I have seen that there are functions here that are triggered following a successful user logon.
There is no problem for users that do not have spaces in their name (e.g. JohnS). They can change their AD password, and can still log in to WinCC OA afterwards. I can see the _Users.Password datapoint element changing as their encrypted password is updated.
Can anyone help with this? Is there some further function that I need to override in my UserDefined class? Or adapt / modify other functions? At present, there no changes other than to the UserDefined authentication class.
email@example.com wrote: ↑Mon Feb 10, 2020 5:30 pmI have inherited my UserDefined authentication class from the WinCC OA AD authentication class (OaAuthMethodAD). As far as possible, I try to call the function provided by that class. For instance, in my implementation of CheckUserPassword, I replace underscores in the username with spaces, and then call the OaAuthMethodAD implementation of CheckUserPassword.
Perhaps you should implement your own 'isUserVerified' instead of 'checkUserPassword'. The 'isUserVerified' function does the actual user & password verification, so this might be a better place convert the user name back to the actual name.
But I can now get to work some days, and I have tried implementing my own isUserVerified function as you suggest. I can see that it is getting called but I cannot get it to successfully authenticate a user.
I have worked out that isUserVerified takes two string parameters, username and password, but as the implementation of OaAuthMethodAD is in a protected file, I cannot see how it is being used, or what return value is expected. I have tried returning a BOOL (both TRUE and FALSE at different times). I have also tried saying it returns an OaAuthenticationError and returning OaAuthenticationError::None.
But OaAuthMethodAD::checkUserPassword always return -9, and I cannot log in except as root.
Do you have any further suggestions, please?
0 No error (scripts\libs\classes\auth\OaAuthenticationError.ctl)
from my experience I would say that your OS has no Domain Name ( getOSDomainName() returns an empty string) or verifyOSUser() fails.
But I thought that the idea of using my own implementation of isUserVerified was that I could then have control whether or not a user was authenticated. That is not happening. As I said, I have tried returning different things from my implementation of isUserVerified, but OaAuthMethodAD::checkUserPassword always ignores what I return from isUserVerified, and returns -9.
It seems to me that the function OaAuthMethodAD::getMustCreateUser is doing two separate things. Most obviously it is indicating whether user details need to be added to the WinCC OA database. But if the user already exists in the WinCC OA database, it is checking if that user's password needs to be updated. If a password update is required, it is using the _CtrlCommandInterface_2 datapoint to request this.
So I have got things working by including this functionality in my implementation of getMustCreateUser.
Having done this, I now realise that there is little point in my user defined authentication class inheriting from OaAuthMethodAD. I have therefore rewritten my class to inherit just from OaAuthMethod.
But I have one remaining question: is there a library function available in WinCC OA to help me with accessing _CtrlCommandInterfacae_2, and waiting for a response in the Result datapoint element? I'm guessing it will be in CommandInterface, but that it encrypted so I cannot see what is available. If not, no problem, I have got something working.