We have started to use the above to provide non-_user authentication and authorisation (along with CLIENT-PRINCIPAL) for our app.
Part of my job this week is to start writing unit tests (yawn. I know it's really important, but, still, yawn) for the app. One of the tests I want to make is to ensure that the authentication and authorisation work as designed. To that end, I need to fail a test if there are no domains in the database, or the domains have the wrong password etc etc
1) how can I tell if LOAD-DOMAINS("MyDb") has no domains to load
2) how can I create a domain to load (this is, after all, an automated test suite!)
3) I presume that a :SEAL will fail if the password is incorrect
Any clues ?
ok. Need to dump and load the _sec-authentication-system _sec-authentication-domain from the command line.
Helpfully, the code to do this is encrypted (_lodsec.p and _dmpsec.p)
Anyone from progress care to tell me how to dump and load these records automatically ? Or will I have to work it out myself the hard way ... ?
Thanks!
Really struggling with this now. Can someone answer how the _sec-authentication-domain records are created / kept. If I dump the _sec-authentication-domain table, do I have to load it into a database with the same name, or logical name ? I've just tried dumping from one database and loading into a different database name (using the data admin tools ) and client-principal now fails.
I don't know how others do this, but I do very simple things.
First I run a simple .p that in a batch client that connects to the database using command line options. The .p contains this statement in it to do that actual load:
"run prodict/load_d.p (input "_sec-authentication-domain", input cSourceDir)."
The value of cSourceDir is the file system directory specifiication of where the _sec-authentication-domain.d file resides.
The _sec-authentication-domain.d files contains a line for ldbname, but so far it has never caused the load to fail when loading into a database with a different logical name.
I do run into errors, which are captured in the file _sec-authentication-domain.e, if any of the records already exist. The procedure prodict/load_d.p seems to stop on the first error. In my test scripts I clear any .e file before running the load, and then check for a .e file afterwards to see if an error occurs.
OpenEdge won't tell you what is loaded, so I manually verify the load in my test script. Generally I list the domain records found in _sec-authentication-domain with a FOR-EACH statement and capture the output.
When I'm sure the _sec-authentication-domain records were loaded into the database correctly, and the Security-Policy:Load-Domains() has completed successfully, the Client-Principal operations usually work ok.
Hope this is helpful,
Mike Jacobs
Thanks - this only confirms that I must be doing something really
stupid, because I simply can't SET-CLIENT or SET-DB-CLIENT without an
error.
HHrrrmmpphhh.
On 10 February 2011 18:58, Michael Jacobs
What is in ERROR-STATUS? It may provide a clue to what the problem is.
Mike Jacobs
The error message is "failed MyDB client principal validation (13687)
I've narrowed the problem down to this code
DEF VAR ClientPrincipal AS HANDLE NO-UNDO.
SECURITY-POLICY:REGISTER-DOMAIN("MyApp","mypassword") NO-ERROR.
SECURITY-POLICY:LOCK-REGISTRATION() NO-ERROR.
CREATE CLIENT-PRINCIPAL ClientPrincipal.
ASSIGN ClientPrincipal:SESSION-ID = GUID(GENERATE-UUID)
ClientPrincipal:USER-ID = "[TestUnit]"
ClientPrincipal:DOMAIN-NAME = "MyDB".
ClientPrincipal:SEAL("mypassword") .
SECURITY-POLICY:SET-CLIENT(ClientPrincipal) .
If I run this program without a db connected, it works fine. If I run with MyDb connected, I get the error.
1) I have now found the "Trust Application Domain" option hidden away in the DB Options menu !! Yay! The program now works again
2) However, if I uncheck this option, and create database security records (with "MyApp" as a domain, and "mypassword" as the access key) then the program fails again
*BLUSH*
found the problem - it was due to me error handling
Writing a unit test, I had done the following
result = Authenticate("DummyDomain","myuser","mypassword")
assertFalse(result)
reasult = Authenticate("Domain","myuser","mypassword")
assertTrue(result)
and in the authentication method I had
ROUTINE-LEVEL ON ERROR UNDO, THROW.
...
[snip]
method Authenticate()
[snip]
SET-DB-CLIENT(ClientPrincipal,"MyDB") .
IF ERROR-STATUS:NUM-MESSAGES GT 0 THEN RETURN ERROR SUBSTITUTE("Failed to set DB Client. Invalid credentials [&1]",ERROR-STATUS:GET-MESSAGE(1)).
[snip]
the problem was that the first check raised an error, but that was expected (wrong domain). The second test *passed* (right credentials). However the ERROR-STATUS handle still had the error data from the first error, because I have not encountered any other errors since, and hence returned the ERROR from the first check ...
So, I fixed the problem by adding the missing NO-ERROR to the SET-DB-CLIENT statement
Man, that was tough to find !
And here I was thinking that it might have something to do with the way you were spelling "reasult"...